2012-06-20 99 views
2

我试图在共享内存段上存储一个std :: map。但我无法恢复地图。Cast void * to std :: map

我创建共享内存段(使用下面的类)并为其分配地图地址。

但是,当我尝试恢复它,我得到一个不好的指针。

下面是一些代码片段:

// This is in my header file 
    CSharedMem * shMem; 
    // This is in my cpp file - inside my class constructor 
    shMem = new CSharedMem("MyShMem", 16536); 
    void * ptr = shMem->GetAddress(); 
    std::map<int,int> myMap; 
    ptr = &myMap; 
    shMem-ReleaseAddress(); 

    // This is inside another function 
    void * ptr = shMem->GetAdress(); 

    std::map<int,int> myMap = *static_cast<std::map<int,int> *> (ptr); 

没有人有线索?

CSharedMem类 头文件

#pragma once 

    #include <string> 

    class CSharedMem 
    { 
    public: 
    CSharedMem(const std::string& name, std::size_t size); 
    ~CSharedMem(); 

    void* GetAddress() const; 
    void ReleaseAddress(); 
    bool IsShared() const; 
    private: 
    bool shared_; 
    void* address_; 

    private: 
    void* shm_; 
    void* mtx_; 
    }; 

CPP文件:

#include "StdAfx.h" 
    #include "SharedMem.h" 
    #include <windows.h> 
    CSharedMem::CSharedMem(const std::string& name, std::size_t size) 
    : shared_(false), 
    address_(NULL) 
    { 
    shm_ = CreateFileMapping(INVALID_HANDLE_VALUE, 
          NULL, PAGE_READWRITE, 
          0, 
          static_cast<DWORD>(size), 
          name.c_str()); 
    if(shm_ == INVALID_HANDLE_VALUE) 
      throw std::exception("Failed to allocate shared memory."); 

    if(GetLastError() == ERROR_ALREADY_EXISTS) 
      shared_ = true; 

    address_ = MapViewOfFile(shm_, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); 
    if(address_ == NULL) 
      throw std::exception("Failed to map shared memory."); 

    if(!shared_) 
      std::memset(address_, 0, size); 

    mtx_ = CreateMutex(NULL, FALSE, (name + "MTX").c_str()); 
    if(mtx_ == INVALID_HANDLE_VALUE) 
      throw std::exception("Failed to create shared mutex."); 
    } 

    CSharedMem::~CSharedMem() 
    { 
    UnmapViewOfFile(address_); 
    CloseHandle(mtx_); 
    } 
    void* CSharedMem::GetAddress() const 
    { 
    if(WaitForSingleObject(mtx_, INFINITE) != WAIT_OBJECT_0) 
      throw std::exception("Failed to obtain access to shared memory."); 

    return address_; 
    } 

    void CSharedMem::ReleaseAddress() 
    { 
      ReleaseMutex(mtx_); 
    } 

    bool CSharedMem::IsShared() const 
    { 
      return shared_; 
    } 
+2

你的代码不可能工作。问题比看起来更复杂。阅读STL分配器和新的放置位置。你需要两个概念。你也必须在固定的地址分配你的共享内存段。 –

回答

4

东西是腥这个逻辑:

您使用 shMem->GetAddress()获取地址
void * ptr = shMem->GetAddress(); 
std::map<int,int> myMap; 
ptr = &myMap; 
shMem->ReleaseAddress(); 

通知,但随后声明一个局部变量myMap,然后分配ptr本地变量的地址。这意味着您实际上不会再有ptr指向该共享内存。

我不确定这个问题的解决方法是什么,因为我不确定我看到你在这里做什么。如果你打算投的共享内存,你必须是一个指向一个地图,或许你的意思是这样的:

void * ptr = shMem->GetAddress(); 

/* Construct a map at the given address using placement new. */ 
new (ptr) std::map<int, int>(); 
shMem-ReleaseAddress(); 

之后,你可以检索地图:

void* ptr = shMem->GetAdress(); 

/* Note the use of a reference here so we don't just make a copy. */ 
std::map<int,int> myMap& = *static_cast<std::map<int,int> *> (ptr); 

这么说,我这是非常令人怀疑的,因为在map内部分配的指针在创建它们的过程中是本地的,而不是共享的。你可能需要用分配器来做一些事情才能使它正常工作。

希望这会有所帮助!

+0

我认为你是对的。我可以在早上上班的时候(从这里开始9个小时)进行测试。谢谢你的提示!当我测试它时,我会再次回复。 – George

4

关于上面的评论,这并不像听起来那么简单。如果跨进程使用共享内存,则无法传递STL容器。

但是,您可以使用boost::interprocess库中的容器。这个库专门提供了可以在共享内存段中使用的容器(vector,deque,set,map),文档提供了很多示例。