能否利用Boost Interprocess共享非托管内存指针?技术问询
进程间共享非托管内存指针的问题解答
核心结论
不能直接将进程B中malloc分配的非托管内存指针共享给进程A,这是完全不可行的。
原因很简单:每个进程拥有独立的虚拟地址空间,进程B里的指针p是该进程虚拟地址空间中的地址,到了进程A的虚拟地址空间中,这个地址要么指向完全无关的内存区域,要么直接是无效地址,必然导致访问错误或崩溃。你尝试用offset_ptr传递二级指针的方案失败,本质就是因为最终保存的p是进程B的私有虚拟地址,对进程A毫无意义。
替代方案(无需深拷贝)
如果不想做复杂的深拷贝,可参考以下几种思路:
1. 让库函数直接在共享内存中分配内存
既然你用了Boost.Interprocess的managed_shared_memory,可以修改或封装test1函数,让它从共享内存分配器中获取内存,而非调用malloc:
- 可以给
test1新增参数,传入共享内存的分配器实例; - 或者在进程B中预先在共享内存里分配足够空间,让
test1直接将数据写入这片空间。
这样分配的内存本身就在共享区域,用offset_ptr处理地址偏移后,进程A可以直接访问。
2. 用文件映射(mmap)替代私有malloc
进程B创建一个临时文件,通过mmap将其映射到自身内存空间,然后让libtest.so的函数把数据写入这个映射区域。进程A只需映射同一个文件,就能直接访问数据。
- 注意:如果内存结构中包含指针,需要将这些指针改为相对于映射区域起始地址的偏移量,而非绝对虚拟地址,否则进程A无法正确解析。
3. 采用代理模式通过IPC访问
让进程B作为服务端,保留对复杂内存结构的控制权。进程A通过IPC机制(管道、套接字、共享内存中的命令队列)向进程B发送请求,由进程B负责读取复杂结构的数据并返回结果,或直接操作后将结果同步到共享内存的简单结构中。这种方式无需共享原始指针,由服务端代理处理复杂结构的访问逻辑。
4. 劫持malloc改用共享内存分配器
如果无法修改libtest.so的代码,可以通过动态链接的技巧劫持malloc:
- 在进程B中加载
libtest.so之前,用dlopen加载自定义的分配器库,通过RTLD_NEXT替换malloc实现,让其从managed_shared_memory中分配内存。这种方式不需要修改原库代码,就能让test1分配的内存直接进入共享区域。
内容的提问来源于stack exchange,提问作者prgbenz
相关产品推荐
相关产品推荐

