TMapFile
This class implements a shared memory region mapped to a file.
Objects can be placed into this shared memory area using the Add()
member function. To actually place a copy of the object is shared
memory call Update() also whenever the mapped object(s) change(s)
call Update() to put a fresh copy in the shared memory. This extra
step is necessary since it is not possible to share objects with
virtual pointers between processes (the vtbl ptr points to the
originators unique address space and can not be used by the
consumer process(es)). Consumer processes can map the memory region
from this file and access the objects stored in it via the Get()
method (which returns a copy of the object stored in the shared
memory with correct vtbl ptr set). Only objects of classes with a
Streamer() member function defined can be shared.
I know the current implementation is not ideal (you need to copy to
and from the shared memory file) but the main problem is with the
class' virtual_table pointer. This pointer points to a table unique
for every process. Therefore, different options are:
1) One could allocate an object directly in shared memory in the
producer, but the consumer still has to copy the object from
shared memory into a local object which has the correct vtbl
pointer for that process (copy ctor's can be used for creating
the local copy).
2) Another possibility is to only allow objects without virtual
functions in shared memory (like simple C structs), or to
forbid (how?) the consumer from calling any virtual functions
of the objects in shared memory.
3) A last option is to copy the object internals to shared memory
and copy them again from there. This is what is done in the
TMapFile (using the object Streamer() to make a deep copy).
Option 1) saves one copy, but requires solid copy ctor's (along the
full inheritance chain) to rebuild the object in the consumer. Most
classes don't provide these copy ctor's, especially not when objects
contain collections, etc. 2) is too limiting or dangerous (calling
accidentally a virtual function will segv). So since we have a
robust Streamer mechanism I opted for 3).