gpt4 book ai didi

c++ - 在进程之间共享类指针

转载 作者:搜寻专家 更新时间:2023-10-31 00:39:15 24 4
gpt4 key购买 nike

我有一个服务器库,我的客户端可执行文件将其注入(inject)远程进程。服务器负责设置某种 IPC/RPC 实现,以允许客户端与远程进程无缝通信。

更新

查看以下服务器端 header :

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
using namespace boost::interprocess;

typedef allocator<int, managed_shared_memory::segment_manager> ShmIntAllocator;
typedef vector<int, ShmIntAllocator> IntVector;

class A
{
public:
A();
A(string str, offset_ptr<IntVector> ints)
: m_str(string(str)), m_ints(ints) {};
~A();

string m_str;
offset_ptr<IntVector> m_ints;
};

class B
{
public:
B();
B(offset_ptr<A> obj) : m_obj(obj);
~B();
VOID DoSomethingUseful()
{
MessageBoxA(NULL, m_obj->m_str.c_str(), "SomethingUseful", MB_ICONINFORMATION);
}

offset_ptr<A> m_obj;
};

这是服务器端的实现:

managed_shared_memory g_shm;
offset_ptr<A> g_objA = nullptr;
PVOID g_hMem = nullptr;

BOOL StartServer()
// Create a shared memory pool
try {
g_shm = managed_shared_memory(create_only, "MySharedMem", OVR_MAPSIZE);
} catch(interprocess_exception& e) {
std::string msg(e.what());
MessageBoxA(NULL, msg.c_str(), "Error", MB_ICONERROR);
return FALSE;
}

// Construct a local class instance
const ShmIntAllocator alloc_intVector (g_shm.get_segment_manager());
offset_ptr<IntVector> ints = g_shm.construct<IntVector>(unique_instance)(alloc_intVector);
ints->push_back(10);
ints->push_back(20);
ints->push_back(30);
g_objA = new A("Testing", ints);
B objB(g_objA);

// Copy data into shared memory
size_t len = sizeof(objB); // <-- Doesn't seem to make a difference if I set this to be something higher
g_hMem = g_shm.allocate(len);
std::memcpy(g_hMem, &objB, len);
return TRUE;
}

VOID StopServer()
{
// Free used resources

if(g_objA) {
delete g_objA;
g_objA = nullptr;
}

try{
g_shm.destroy<B>(unique_instance);
g_shm.deallocate(g_hMem);
g_hMem = nullptr;
shared_memory_object::remove("MySharedMem");
} catch(interprocess_exception& e) {
std::string msg(e.what());
MessageBoxA(NULL, msg.c_str(), "Error", MB_ICONERROR);
}
}

和客户端实现:

BOOL Connect()
{
// Grab the shared memory pool and extract the class
managed_shared_memory shm(open_only, "MySharedMem");
std::pair<B*, std::size_t> ret = shm.find<B>(unique_instance); // <-- Always ends up being 0x00000000!
B *objB = static_cast<B*>(ret.first);
if(!objB) return FALSE;
objB->DoSomethingUseful();
return TRUE;
}


您会注意到 managed_shared_memory::find() 始终无法返回指向客户端的有效指针。但据我所知,代码是完全有效的。没有编译器警告或错误,到目前为止一切似乎都运行顺利。

那么为什么会失败呢?我怎样才能让它按预期工作?

最佳答案

指针的不同地址空间

当您分享值(value)观时,一切都一目了然。例如当在共享内存中放入一个float 值如1234.5,在另一边你可以简单地读取它。

但是当您共享复杂对象(包含指针)时,会出现一个重要问题。两个进程的地址空间完全不同,截然不同。例如,您不能将 std::vector 对象放在共享内存中,因为它有一个指向其在 process1 中的数据的指针,例如0x1ABF212 并且这个数字对 process2 没有意义。

因此,你必须在共享内存中将std::vector 的各项一一记下。阅读有关共享复杂数据的序列化技术。

此外,如果您坚持要在进程之间将复杂对象作为唯一对象共享,您可以为这些对象创建特定的内存分配器。

AFAIK Boost.Interprocess 有那个分配器。它管理共享内存并在共享内存中创建指针,这对两个进程都有意义。

抱歉含糊不清,我的英语不好

关于c++ - 在进程之间共享类指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16514795/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com