|
Boost Users : |
From: Cyril Picat (cpicat_at_[hidden])
Date: 2008-05-29 11:45:49
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_at_Vxml_oarchive_at_archive@boost@@@MyCla
ss@@AAEXAAVxml_oarchive_at_archive@boost@@I_at_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_at_Vxml_oarchive_at_archive@boost@@VMyClass@@@access_at_seria
lization_at_boost@@SAXAAVxml_oarchive_at_archive@2_at_AAVMyClass@@I_at_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
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net