I ended up checking if the remote process is 32-bit or 64-bit at runtime, and then writing the correct structure to shared memory before sending the message.
For example, here you can use the message TVM_GETITEM , even if there is a 32-bit and a 64-bit mix between the caller and the receiver:
template <typename AddrType> struct TVITEM_3264 { UINT mask; AddrType hItem; UINT state; UINT stateMask; AddrType pszText; int cchTextMax; int iImage; int iSelectedImage; int cChildren; AddrType lParam; }; typedef TVITEM_3264<UINT32> TVITEM32; typedef TVITEM_3264<UINT64> TVITEM64;
The sharedMem->getSharedMemory is a small helper function for getting a pointer to a shared memory region; an optional function argument indicates the offset value. The important thing is that the shared memory area should always be in a 32-bit address space (so that even a 32-bit remote process can access it).
source share