在哪里放置BOOST_CLASS_EXPORT为boost :: serialization? [英] Where to put BOOST_CLASS_EXPORT for boost::serialization?
问题描述
我试图序列化一个指向多态类 Shape
的指针。所以我需要使用 BOOST_CLASS_EXPORT
宏来定义每个子类的GUID。
让我先展示一个最小的测试用例:
shapes.hpp
#include< boost / serialization / access.hpp>
#include< boost / serialization / base_object.hpp>
#include< boost / serialization / export.hpp>
类Shape {
friend class boost :: serialization :: access;
template< typename Archive>
void serialize(Archive& ar,unsigned int const version){
//无需执行
}
public:
virtual〜Shape ){}
};
class Rect:public Shape {
friend class boost :: serialization :: access;
template< typename Archive>
void serialize(Archive& ar,unsigned int const version){
ar& boost :: serialization :: base_object< Shape>(* this);
}
public:
virtual〜Rect(){}
};
#ifdef EXPORT_IN_HEADER
BOOST_CLASS_EXPORT(Rect)
#endif
$ b b
export.cpp
#include< boost / serialization / export.hpp>
#includeshapes.hpp
#ifdef EXPORT_IN_OBJECT
BOOST_CLASS_EXPORT(Rect)
#endif
main.cpp
include< iostream>
#include< boost / archive / text_oarchive.hpp>
#include< boost / serialization / export.hpp>
#includeshapes.hpp
#ifdef EXPORT_IN_MAIN
BOOST_CLASS_EXPORT(Rect)
#endif
int main b $ b Shape * shape = new Rect();
boost :: archive :: text_oarchive ar(std :: cout);
ar<<形状;
}
在gcc上,我使用
g ++ -omain main.cpp export.cpp -Wl,-Bstatic -lboost_serialization-mt -Wl,-Bdynamic -DEXPORT_IN_XXX
这里, export.cpp
可能看起来有点傻。在我的实际情况中,它包含一个使用PIMPL成语的封闭类,并尝试序列化其(多态) Shape
实现。重要的是: BOOST_CLASS_EXPORT
可能位于与调用序列化的代码不同的不同的对象文件中。
所以这里的问题:在哪里使用 BOOST_CLASS_EXPORT
?我有三个选项,可以使用 EXPORT_IN_XXX
宏启用。
- p>
EXPORT_IN_MAIN
可以工作,但不是我想要的。调用序列化的代码不需要知道PIMPL类的实现细节。 -
EXPORT_IN_OBJECT
编译,但不工作:它导致一个boost :: archive :: archive_exception
与消息unregistered void cast
。根据文档,这应该通过序列化基础来解决使用boost :: serialization :: base_object
的类,像我一样,但它不帮助。 - p>
EXPORT_IN_HEADER
甚至不编译。宏BOOST_CLASS_EXPORT
扩展为模板特化(我们希望在头文件中),但也扩展到其中的静态成员的定义。所以我得到一个链接器错误关于一个多个定义的'boost :: archive :: detail :: init_guid< Rect> :: guid_initializer'
。
如果重要,我使用g ++ 4.4.3和Boost 1.40。
我最后把所有的序列化代码放在一个标题 s11n.h
中,它包含在调用序列化的CPP文件中。基本上,上面描述的 EXPORT_IN_MAIN
场景,但在不同文件中的 BOOST_CLASS_EXPORT
宏调用。
这只有工作,只要只有一个编译单元包括 s11n.h
,当然,所以虽然它现在工作,没有真正的解决方案...
I'm trying to serialize a pointer to a polymorphic class Shape
. So I need to use the BOOST_CLASS_EXPORT
macro to define a GUID for each subclass. The problem: where to put it?
Let me show a minimal test case first:
shapes.hpp
#include <boost/serialization/access.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
class Shape {
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive &ar, unsigned int const version) {
// nothing to do
}
public:
virtual ~Shape() { }
};
class Rect : public Shape {
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive &ar, unsigned int const version) {
ar & boost::serialization::base_object<Shape>(*this);
}
public:
virtual ~Rect() { }
};
#ifdef EXPORT_IN_HEADER
BOOST_CLASS_EXPORT(Rect)
#endif
export.cpp
#include <boost/serialization/export.hpp>
#include "shapes.hpp"
#ifdef EXPORT_IN_OBJECT
BOOST_CLASS_EXPORT(Rect)
#endif
main.cpp
#include <iostream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include "shapes.hpp"
#ifdef EXPORT_IN_MAIN
BOOST_CLASS_EXPORT(Rect)
#endif
int main() {
Shape *shape = new Rect();
boost::archive::text_oarchive ar(std::cout);
ar << shape;
}
On gcc, I compile these with
g++ -omain main.cpp export.cpp -Wl,-Bstatic -lboost_serialization-mt -Wl,-Bdynamic -DEXPORT_IN_XXX
Here, export.cpp
may look a bit silly. In my actual situation, it contains an enclosing class that uses the PIMPL idiom, and tries to serialize its (polymorphic) Shape
implementation. The important point is: the BOOST_CLASS_EXPORT
could be in a different object file than the code that invokes the serialization.
So here's the problem: where to use BOOST_CLASS_EXPORT
? I have three options, which can be enabled using the EXPORT_IN_XXX
macros.
EXPORT_IN_MAIN
works, but is not what I want. The code invoking the serialization should not need to know about the implementation details of the PIMPL class.EXPORT_IN_OBJECT
compiles, but does not work: it results in aboost::archive::archive_exception
with the messageunregistered void cast
. According to the documentation, this should be solved by serializing base classes usingboost::serialization::base_object
, like I did, but it doesn't help.EXPORT_IN_HEADER
does not even compile. The macroBOOST_CLASS_EXPORT
expands to a template specialization (which we'd like to be in the header file), but also to the definitiof of a static member therein. So I get a linker error about amultiple definition of 'boost::archive::detail::init_guid<Rect>::guid_initializer'
.
If it matters, I'm using g++ 4.4.3 and Boost 1.40.
I ended up putting all the serialization code in a header s11n.h
that is included from the CPP file that invokes the serialization. Essentially, the EXPORT_IN_MAIN
scenario I sketched above, but with the BOOST_CLASS_EXPORT
macro invocations in a different file.
This only works as long as only one compilation unit includes s11n.h
, of course, so although it works for now, it's no real solution...
这篇关于在哪里放置BOOST_CLASS_EXPORT为boost :: serialization?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!