I have a server library which my client executable injects into a remote process. It is the server's responsibility to set up some sort of IPC/RPC implementation to allow the client to seamlessly communicate with the remote process.
Update
Take a look at the following server-side 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; }; And here's the server-side implementation:
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); } } And the client implementation:
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; }
You'll notice that managed_shared_memory::find() always fails to return a valid pointer to the client. But as far as I can tell, the code is perfectly valid. There are no compiler warnings or errors, and everything appears to run smoothly up until this point.
So why is this failing? How can I get this to work as expected?