
Hi everybody, I have just tried a simple example of a class serialization in a DLL and did not manage to make it work. I have been using Boost serialization since a while but until now I was putting all the serialization code in the .hpp. By the way thanks Robert (and Boost) for this great library. I am using MSVC 8.0 and Boost 1.34.1. I have tried the same with Boost Serialization 1.36 (head of Boost) without any success. My test is the following. The class MyClass in declared in a DLL boost-example.dll built from Example.cpp. A test program Example.t.cpp linked with boost-example.dll try to serialize MyClass to an XML archive. The files are the following: //////// Example.hpp #if _MSC_VER > 1000 #pragma once #endif // Do NOT include any headers after this point #if (defined(__COMPILING_Example_CPP__) && defined(WIN32)) #define _LIBSPEC __declspec(dllexport) #else #define _LIBSPEC #endif class _LIBSPEC MyClass { public: MyClass(); private: friend class boost::serialization::access; template <class Archive> void serialize(Archive & ar, const unsigned int version); std::string m_str; }; //////// Example.cpp #include <string> #include "boost/archive/xml_oarchive.hpp" #include "boost/archive/xml_iarchive.hpp" #include "boost/serialization/nvp.hpp" #include "boost/serialization/export.hpp" #include "Example.hpp" using namespace std; BOOST_CLASS_EXPORT(MyClass); // should explicity instantiate template for // xml_oarchive and xml_iarchive MyClass::MyClass() : m_str("MyClass") {} template <class Archive> void MyClass::serialize(Archive & ar, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(m_str); } //////// Example.t.cpp #include <iostream> #include <fstream> #include "boost/archive/xml_oarchive.hpp" #include "boost/serialization/nvp.hpp" #include "Example.hpp" using namespace std; int main(int argc, char* argv[]) { MyClass myClass; // try to serialize MyClass using an XML archive ofstream ofs("myClass.xml"); if( !ofs ) { cout << "ERROR: Could not open myClass.xml for writing"; return EXIT_FAILURE; } try { boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(myClass); } catch (const std::exception& e) { cout << "failed to serialize MyClass with xml_oarchive: " << e.what(); ofs.setstate(ios::failbit); } return EXIT_SUCCESS; } When compiling this, I got an error at link time for Example.t: Example.t.obj : error LNK2019: unresolved external symbol "private: void __thisc all MyClass::serialize<class boost::archive::xml_oarchive>(class boost::archive: :xml_oarchive &,unsigned int)" (??$serialize@Vxml_oarchive@archive@boost@@@MyCla ss@@AAEXAAVxml_oarchive@archive@boost@@I@Z) referenced in function "public: stat ic void __cdecl boost::serialization::access::serialize<class boost::archive::xm l_oarchive,class MyClass>(class boost::archive::xml_oarchive &,class MyClass &,u nsigned int)" (??$serialize@Vxml_oarchive@archive@boost@@VMyClass@@@access@seria lization@boost@@SAXAAVxml_oarchive@archive@2@AAVMyClass@@I@Z) I have taken a look at boost-example.dll with Dependency Walker and there are quite a few symbols exported for MyClass and boost::archive::xml_oarchive. Any clue of what is going on? The strange thing is that I have another more complex example with an abstract class and derived classes in separate DLLs where I serialize to the base pointer and everything is compiling and working fine (both with 1.34.1 and HEAD). I have read the doc ('Exporting Class Serialization') and have seen in the logs that a lot have changed regarding export since 1.34.1. In what I have understood, the fix was concerning cases where the macro BOOST_CLASS_EXPORT() is used in the .hpp, leading to multiple registrations, and not in the .cpp as I am doing. Am I right? By the way, I have noticed a little typo in the doc concerning void_cast_register. In the doc the proposed syntax is 'boost::serialization::void_cast_register<derived, base>(static_cast<base *>(NULL), static_cast<derived *>(NULL))' although in my experience the correct syntax is: 'boost::serialization::void_cast_register<derived, base>(static_cast<derived*>(NULL),static_cast<base*>(NULL))' Thanks in advance, Cyril Picat