Put the serialization of a class into a DLL
I'm looking for a (working) example for externally serializing a class-structure in a DLL. Currently I'm not able to find any examples for that. The Boost documentation is just stating some macros, the forums and newsgroups are just discussing specific problems with their solutions.
So I'm asking for an example for (externally) serializing a class-structure like the following. Along with the class-code I added some code of mine for serializing (which does not work, see bottom for error-message).
class Foo
{
public:
Foo() { number_ = 0; }
virtual ~Foo() {}
int getNumber() { return number_; }
void setNumber( int var ) { number_ = var; }
private:
int number_;
};
class Bar : public Foo
{
public:
Bar() { doubleNumber_ = 0.0; }
virtual ~Bar() {}
double getDouble() { return doubleNumber_; }
void setDouble( double var ) { doubleNumber_ = var; }
private:
double doubleNumber_;
};
All what I've got so far is code like this:
serializeFoo.h
#ifndef _SERIALIZE_FOO_H_
#define _SERIALIZE_FOO_H_
#include "Foo.h"
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/version.hpp>
namespace boost {
namespace serialization {
template <typename Archive>
void save(Archive& ar, const Foo& object, const unsigned int version)
{
ar << object.getNumber();
}
template <typename Archive>
void load(Archive& ar, Foo& object, const unsigned int version)
{
int number;
ar >> number;
object.setNumber(number);
}
}} //namespace brackets
BOOST_SERIALIZATION_SPLIT_FREE( Foo )
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT_KEY( Foo )
#endif //_SERIALIZE_FOO_H_
serializeFoo.cpp
#include "serializeFoo.h"
BOOST_CLASS_EXPORT_IMPLEMENT( Foo )
serializeBar.h :
#ifndef _SERIALIZE_BAR_H_
#define _SERIALIZE_BAR_H_
#include "Bar.h"
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/version.hpp>
namespace boost {
namespace serialization {
template <typename Archive>
void save(Archive& ar, const Bar& object, const unsigned int version)
{
ar << base_object<Foo>(object);
ar << object.getDouble();
}
template <typename Archive>
void load(Archive& ar, Bar& object, const unsigned int version)
{
double doubleNumber;
ar >> doubleNumber;
object.setDouble(doubleNumber);
}
}} //namespace brackets
BOOST_SERIALIZATION_SPLIT_FREE( Bar )
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT_KEY( Bar )
#endif //_SERIALIZE_BAR_H_
serializeBar.cpp :
#include "serializeBar.h"
BOOST_CLASS_EXPORT_IMPLEMENT( Bar )
The serialization-code goes into a DLL and should be used in another project using classes Foo and Bar. Everything compiles fine, but at runtime I get the message
unregistered class - derived class not registered or exported
So did I used the wrong macros? Do I miss a macro? Is the above code right or is there some kind of structural error? Perhaps this could be useful for a lot of other people too, I don't think that putting the serialization of a class into a DLL is very exotic...
I ran into a similar issue recently, 3 years after this question was asked. I finally found out a workaround to solve it. In the example above.
Bar
is a subclass of Foo
, so it must be registered/exported; serializeFoo.cpp
instantiates a GUID template class to register/export Foo
; serializeBar.cpp
instantiates a GUID template class to register/export Bar
; I assume in your exe, while you are trying to serialise a Foo*
pointer pointing to a Bar
object, you got the "unregistered class blahblah" error. This is because Boost.Serialization somehow does not properly generate a GUID for class Bar
before the serialize function is called.
I don't know why this happens, but it seems that GUID is generated in a lazy way -- if none of the symbols from the translation unit serializeBar.cpp
is used, none of the instantiation/initialization code defined in that translation unit will be performed -- that includes the class registration/exportation of Bar
.
To prove that, you can try to use a (dummy) symbol in serializeBar.cpp
(eg by calling a dummy function implemented in serializeBar.cpp
) before calling any serialization function for Foo*
. The issue should disappear.
Hope it helps.
the test suite and demo distributed with the serialization library demonstrate exactly this facility. So first make sure that works. Then compare your example to it.
Robert Ramey
"Honestly, IMHO, at some points, Boost Serialization crosses the border of what is reliably possible with pure c++ build model w/o external tools..."
hmmmmmm - so it crosses the boarder as what's possible? You're pretty much correct in spirit though. Great effort was expended to implement everything that was considered necessary for such a package to be acceptable into boost.
RR
Hard to tell... There are many chances for things to go wrong. I recommend to download the test code for boost serialization (www.boost.org/doc/libs/1_48_0/libs/serialization/test/). Have a look at the test cases around Ah, A.cpp and dll_a.cpp (which basically test your scenario) and try to make it work outside of the boost test system: use your build environment, try to modify compiler/linker options to match those of boost test suite for your toolset.
Honestly, IMHO, at some points, Boost Serialization crosses the border of what is reliably possible with pure c++ build model w/o external tools...
链接地址: http://www.djcxy.com/p/10412.html上一篇: 执行多个项目
下一篇: 将类的序列化放入DLL中