在OSX上从x86读取共享内存到x64,反之亦然
Reading Shared Memory from x86 to x64 and vice versa on OSX
如果我从64位应用程序创建一个SM,然后在32位应用程序上打开它,它会失败。
//for 64 bit
shared_memory_object( create_only, "test" , read_write) ;
// for 32 bit
shared_memory_object (open_only, "test", read_write);
64位应用程序创建的文件的路径如下:
/private/tmp/boost_interprocess/AD21A54E000000000000000000000000/test
,其中32位应用程序搜索的文件位于路径
/private/tmp/boost_interprocess/AD21A54E00000000/test
因此32位应用程序不能读取该文件。
我在Mac OS X上使用boost 1.47.0。是bug吗?我是否需要做一些设置,使用一些宏来修复它?以前有人遇到过这个问题吗?
共享内存由文件备份很重要吗?如果没有,可以考虑使用底层的Unix共享内存api: shmget、shmat、shmdt和shmctl,它们都在sys/shm.h中声明。我发现它们非常容易使用。
// create some shared memory
int id = shmget(0x12345678, 1024 * 1024, IPC_CREAT | 0666);
if (id >= 0)
{
void* p = shmat(id, 0, 0);
if (p != (void*)-1)
{
initialize_shared_memory(p);
// detach from the shared memory when we are done;
// it will still exist, waiting for another process to access it
shmdt(p);
}
else
{
handle_error();
}
}
else
{
handle_error();
}
另一个进程会使用类似这样的代码来访问共享内存:
// access the shared memory
int id = shmget(0x12345678, 0, 0);
if (id >= 0)
{
// find out how big it is
struct shmid_ds info = { { 0 } };
if (shmctl(id, IPC_STAT, &info) == 0)
printf("%d bytes of shared memoryn", (int)info.shm_segsz);
else
handle_error();
// get its address
void* p = shmat(id, 0, 0);
if (p != (void*)-1)
{
do_something(p);
// detach from the shared memory; it still exists, but we can't get to it
shmdt(p);
}
else
{
handle_error();
}
}
else
{
handle_error();
}
然后,当所有进程使用完共享内存后,使用shmctl(id, IPC_RMID, 0)
将其释放回系统。
可以在命令行中使用ipcs和ipcrm工具来管理共享内存。在第一次编写共享内存代码时,它们对于清除错误非常有用。
说了这么多,我不确定在32位和64位程序之间共享内存。我建议尝试Unix api,如果它们失败了,可能就无法完成了。毕竟,它们是Boost在实现中使用的。
我找到了问题的解决方案,果然是一个bug。
这个错误存在于tmp_dir_helpers.hpp文件中。
inline void get_bootstamp(std::string &s, bool add = false)
{
...
std::size_t char_counter = 0;
long fields[2] = { result.tv_sec, result.tv_usec };
for(std::size_t field = 0; field != 2; ++field){
for(std::size_t i = 0; i != sizeof(long); ++i){
const char *ptr = (const char *)&fields[field];
bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4];
bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)];
}
...
}
本来应该是这样的……
**long long** fields[2] = { result.tv_sec, result.tv_usec };
for(std::size_t field = 0; field != 2; ++field){
for(std::size_t i = 0; i != sizeof(**long long**); ++i)
我已经在boost中为这个错误创建了一个票据。
谢谢。
相关文章:
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 为x86而非x64编译时出错
- 在C++中,将int值赋给enum,反之亦然
- 为什么在 x64 中忽略__stdcall调用约定?
- 使用 VS2015 在 Windows 10 上构建 Fortran .lib x64 位并将其链接到 C++
- 如何在 c++ 中将所有大写字母转换为字符串中的小写字母,反之亦然?
- 加载"D:UsersPublicDocumentsopencvbuildx64vc14binopencv_world340d.dll",找不到或打开PDB文件
- 将通用引用强制转换为可调用的 void 指针,反之亦然
- 用非原子更新原子变量,反之亦然
- VS 2017 使用交叉编译器构建 x64 项目
- 从向量到空指针的 memcpy(反之亦然)不起作用
- 在VS2019项目中集成ImageMagick:x64-windows-static library
- C++变量在调用 x64 程序集函数后重置为 0
- 在 masm x64 上打印具有多个参数
- 在Visual Studio中使用vcpkg使用paho-mqtt x64时出错
- 以 x64 配置访问证书公钥
- 将基类分配给派生对象,反之亦然,以C++以及静态和动态对象之间的差异
- 发布代码的 gdb 堆栈跟踪可读性如何影响 x64?
- 在OSX上从x86读取共享内存到x64,反之亦然
- 我可以在Visual Studio 2008中从Win32解决方案配置编译x64 exe(反之亦然)吗?