我对 std::string
键和大 struct
值放入容器(例如 boost::interprocess::map
)所涉及的堆和按值与引用语义有点混淆 .
这是我的情况,以及我正在使用的一些typedef:
typedef std::string AreaKeyType;
typedef DATA_AREA_DESC AreaMappedType; // DATA_AREA_DESC is a big struct.
typedef std::pair<const AreaKeyType, AreaMappedType> AreaValueType;
typedef boost::interprocess::allocator<AreaValueType, boost::interprocess::managed_shared_memory::segment_manager> AreaShmemAllocator;
typedef boost::interprocess::map<AreaKeyType, AreaMappedType, std::less<AreaKeyType>, AreaShmemAllocator> AreaMap;
这是我如何插入AreaValueType(这是std :: pair的typedef):
AreaValueType A(areaKey, arearec);
anAreaMap->insert(A);
我相信上面的代码将我在本地(非共享内存)堆栈上的std :: pair复制到共享内存区域 . 我可以在boost :: interprocess :: map中获取该共享内存区域的句柄,还是仅限于将该记录整回并整个存储? (换句话说,我可以将类似结构的东西存储到boost进程间映射中,然后更新该记录中的单个字节,或者我必须通过替换DATA_AREA_DESC结构中的所有字节来更新整个记录,全新字节) .
进一步澄清:
-
我有一个普通的旧ANSI C DLL导出api,内部使用C和Boost :: interprocess :: map . 该函数应该在 Map 中创建一个项目,然后返回一个句柄 . 如何在boost :: interprocess :: map中插入一些东西,然后向非C用户返回该实体的句柄,最好转换为
void*
或unsigned long
?我所能做的就是通过查找std :: string键值从共享内存中获取内容,并将新记录写入内存 . 我希望能够保持对共享内存对象的引用 . -
如果我不能直接这样做,我将如何间接地做到这一点?我想我可以保留一个非共享内存std :: vector,并分配一个非共享内存std :: string,它保存areaKey的值,这是一个std :: string,然后执行
void*
的强制转换item返回std::string
然后使用它从共享内存区域中取出一条记录 . 对于一些如此基本的东西来说,这似乎都是非常必要的工作 . 也许boost :: interprocess :: map不是我的要求的正确选择?
我试过了什么?这个,编译,但我不知道我是否正确这样做 . 不知何故,我觉得丑陋内部取消引用从 find
返回的 ::iterator
,然后立即采取其地址如下:
void ** handle; // actually a parameter in my api.
*handle = (void*)&(*anAreaMap->find(areaKey));
Update 以上作品 . 然而,下面答案中非常明智的建议不起作用 . 使用boost :: interprocess :: string会导致完整和完全失败并在运行时崩溃 . 使用std :: string,除非特别是Boost编码std :: string支持的作者,否则无权工作,实际上效果很好 .
1 回答
如果
handle
应该是共享内存中std::pair
的指针,那么你的代码将起作用 provided 你知道areaKey
在 Map 中 . 有's nothing wrong with it except you don' t需要显式演员(如果你做演员,那么static_cast<void*>()
将是首选) .我没有使用
boost::interprocess
但是我认为你需要使用boost::interprocess::string
或std::basic_string
和非默认的分配器作为你的密钥 . 除非boost::interprocess
做了一些奇特的事情,否则使用std::string
会将指向本地内存(用于字符串缓冲区)的指针放入共享内存中,这在另一个进程中没有意义 .这是一个使用带字符串键的映射的测试程序:
不带参数运行它来创建一个新的共享内存段,并至少有一个参数来打开一个现有的共享内存段(无参数调用必须已经在运行) . 在这两种情况下,程序将迭代地从
stdin
读取一个键,在 Map 中插入一个条目,并将内容写入stdout
.