将 void* 强制转换为 std::map
Cast void* to std::map
我正在尝试在共享内存段上存储一个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);
有人知道吗?
C类头文件:
#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_;
}
这个逻辑有些可疑:
void * ptr = shMem->GetAddress();
std::map<int,int> myMap;
ptr = &myMap;
shMem->ReleaseAddress();
请注意,您获取一个带有 shMem->GetAddress()
的地址,但随后声明一个局部变量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
内部将是创建它们的过程的本地指针,而不是共享的。 您可能需要对分配器做一些花哨的事情才能使其正常工作。
希望这有帮助!
根据上面的评论,这并不像听起来那么简单。 如果跨进程使用共享内存,则无法传递 STL 容器。
但是,您可以使用boost::interprocess
库中的容器。 该库专门提供了可以在共享内存段中使用的容器(向量、双端、集合、映射),文档提供了大量示例。
相关文章:
- 将无符号char*转换为std::istream*C++
- 将 int 数组转换为 std::vector<int*>
- 如何将这个std::字符串转换为std::基本字符串
- 哪些类型可以转换为std::any
- 如何在对<char>C++程序进行逆向工程的同时将 std::basic_string 转换为 Rust 可读值?
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- 将函数参数"const char*"转换为"std::string_view"是
- 错误 C2679:二进制"<<":未找到采用类型 'std::string_view' 的右侧操作数的运算符(或者没有可接受的转换)
- 字符转换功能 std::isupper() & std::islower() C++17
- 将函数包装器转换为 std::function
- 如何将 std::ifstream 转换为 std::basic_istream<CharT, Traits>&?
- 显式 std::exception_ptr 转换为 bool 不存在.VS2010 错误?
- 如何将唯一指针的 std::vector 转换为原始指针的 std::span?
- std::转换move构造函数的模板专业化的变体
- STD ::转换如何用特定值初始化函子
- 对C++字符串使用 std 转换
- 等价于元组的std::转换
- std::转换为任意容器
- std::转换顺序保证
- std::转换产生奇怪的输出