[Serialization] Problem serializing directly and through base pointer in the same program.

Hi, I am using Boost.Serialization to serialize classes through a shared_ptr to an abstract base class. Sometimes, I also serialize these classes directly. This was working for me in version 1.40, but not versions 1.41 or 1.44. If I serialize only shared_ptr<BaseClass> instances, everything is fine. If I link in code that serializes the derived class directly, even if that code is never called, serialization of shared_ptr<BaseClass> instances throws an exception ("unregistered class"). A few notes about what I am doing: I am calling BOOST_CLASS_EXPORT in the implementation file for each serializable class. I am using a template function for serialization that accepts any serializable type, creates a new text_oarchiver on the stack, and returns a string. This is called from many places in my application with many different types of things (making it hard to have a central place to put all the BOOST_CLASS_EXPORTs). I am having this problem on RHEL5 with gcc 4.1.2 WITHOUT optimization turned on. It works as expected with -O1 or higher. On WinXP with Visual Studio 2005, it fails in both release and debug mode. The problem also seems to depend on the order that the object files get written into the executable. If I include the file that is calling BOOST_CLASS_EXPORT first, things work as expected, but fail otherwise. (e.g., g++ obj.cpp main.cpp ... works, g++ main.cpp obj.cpp ... fails). Here are 3 source files, obj.h, obj.cpp, main.cpp that demonstrate this problem. The line in main: fromString(toString(obj), obj2); causes the code just before it (using shared_ptr) to fail. If anyone can let me know if I am misusing the library somehow, or if there is a cleaner way to accomplish what I am trying to do, I would be very appreciative. Thanks, Travis Abbott --------------------------8< obj.h 8< -------------------------- #pragma once #include <boost/serialization/void_cast.hpp> #include <string> class Base { public: virtual ~Base() {} virtual std::string name() const = 0; }; class Obj : public Base { public: std::string name() const { return "Obj"; } template<typename Arch> void serialize(Arch& arch, const unsigned version) { boost::serialization::void_cast_register<Obj, Base>( static_cast<Obj*>(NULL), static_cast<Base*>(NULL)); arch & data; } int data; }; --------------------------8< obj.cpp 8< -------------------------- #include "obj.h" #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/export.hpp> BOOST_CLASS_EXPORT(Obj) --------------------------8< main.cpp 8< -------------------------- #include "obj.h" #include <boost/serialization/shared_ptr.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/archive/text_oarchive.hpp> #include <boost/shared_ptr.hpp> #include <iostream> #include <sstream> #include <stdexcept> #include <string> using boost::shared_ptr; using namespace std; template<typename T> string toString(const T& obj) { ostringstream ss; boost::archive::text_oarchive arch(ss); arch << obj; return ss.str(); } template<typename T> void fromString(const string& s, T& obj) { istringstream ss(s); boost::archive::text_iarchive arch(ss); arch >> obj; } int main() { try { shared_ptr<Base> pobj(new Obj), pobj2; fromString(toString(pobj), pobj2); cout << pobj2->name() << endl; // Compiling this causes runtime failure in code above. Obj obj, obj2; fromString(toString(obj), obj2); cout << obj2.name() << endl; } catch (const exception& e) { cerr << "Error: " << e.what() << endl; } return 0; }

Travis Abbott wrote:
if I am misusing the library somehow, or if there is a cleaner way to accomplish what I am trying to do, I would be very appreciative.
One thing I would look into would be to "upgrade" the BOOST_EXPORT_CLASS macros to the new macros ...EXPORT_KEY and ... EXPORT_IMPL as described in the documentation. This addresses some ambiguous situations regarding registration of exportable types. Robert Ramey

On Mon, Sep 20, 2010 at 8:35 PM, Robert Ramey <ramey@rrsd.com> wrote:
Travis Abbott wrote:
if I am misusing the library somehow, or if there is a cleaner way to accomplish what I am trying to do, I would be very appreciative.
One thing I would look into would be to "upgrade" the BOOST_EXPORT_CLASS macros to the new macros ...EXPORT_KEY and ... EXPORT_IMPL as described in the documentation. This addresses some ambiguous situations regarding registration of exportable types.
Robert Ramey
...EXPORT_KEY and ...EXPORT_IMPL did the trick. I missed those in the docs. Thank you for your quick help. Travis Abbott
participants (2)
-
Robert Ramey
-
Travis Abbott