
On Wed, Feb 16, 2011 at 1:43 PM, Loïc Joly <loic.actarus.joly@numericable.fr> wrote:
Le 16/02/2011 20:38, Emil Dotchevski a écrit :
On Wed, Feb 16, 2011 at 5:20 AM, Loïc Joly <loic.actarus.joly@numericable.fr> wrote:
I'm using the std::shared_ptr provided with MSVC 2010. I'd like to be able to use boost.serialization to serialize some of those shared_ptrs. I could find an old thread stating that std::tr1::shared_ptr were not handled (and it looked impossible to make them work). Is the situation the same with std::shared_ptr?
If serializing std::shared_ptr/weak_ptr is impossible then I must have done the impossible in my serialization lib. :)3.
You did not know it was impossible, so you did it :)
To be completely honest, shared_ptr serialization *in general* is not possible. For example, a shared_ptr<int> might have been created by aliasing, and might be pointing an int that is a member in a larger object of user-defined type which is the thing that needs to be serialized when the shared_ptr<int> is saved. You can't, in general, get a pointer to that object from an int pointer. But if the shared_ptr points an object of polymorphic type, then serialization is possible.
It looks like the implementation of the serialization of boost::shared_ptr has changed a lot since that time, and it might be possible to adapt it to std::shared_ptr. From what I understand, however, this serialization needs extra bookeeping which is currently stored inside of the archive class. So it looks like I have to define my own archive to be able to serialize std::shared_ptr. I'm gonna give a thought about that.
The main problem is that shared_ptr can be used in contexts where the pointee type is incomplete, yet to write or read the object you need to be able to call a function in which the type is complete. So you need a registry of read and write functions. In addition, the incomplete type you want to be reading or writing might in fact be a base type (obviously you wouldn't know because it is incomplete), so you need registration for functions that can do a static_cast from one type to another (so you can get a derived pointer from your base pointer.) In addition, to create an object when reading, you need a registry with factory functions. In addition, in order to know if two shared_ptrs point to the same object (of polymorphic type) you have to use dynamic_cast<void *> but again, it needs to happen in a function that the user defines and registers. The bottom line is that you need a bunch of maps where types, casts, and functions are registered, and ideally these maps should maintain the lifetime of the entries correctly so that if a registration comes from a dynamic library, when the library is unloaded the relevant registrations are undone. However, such requirements aren't unique for shared_ptr serialization. In general when something is loaded or saved, the load and save functions may need access to "manager" objects. For example, to load a IDirect3DTexture9 object, the load function needs access to a IDirect3DDevice9 object which is used to create the texture. Therefore, the user must be able to associate arbitrary data (such as a pointer to a IDirect3DDevice9) with any archive, so that load and save functions can get to it from the archive object they take as an argument. If such system exists, it can be used to store the maps needed by the shared_ptr serialization as well. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode