2012-06-20 139 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),文檔提供了很多示例。