Boost 序列化多态寄存器(导出)无法跨文件工作
我在我的项目中使用 boost::serialization
。该项目很大,并且在多个地方序列化我的对象。根据此处的文档,我应该用两个单独的步骤导出我的课程。
.h
文件中的BOOST_EXPORT_KEY()
包含声明。.cpp
文件中的BOOST_EXPOET_IMPLMENT()
包含导出的实例化(定义)。
hier.h
类层次结构,层次结构中有3个类。
/*
B <---+--- D1
|
+--- D2
*/
#include <boost/serialization/base_object.hpp>
class B {
public:
virtual ~B() {}
template < typename Ar >
void serialize(Ar& ar, const int) {
}
} ;
class D1 : public B {
public:
virtual ~D1() {}
template < typename Ar > void serialize(Ar& ar, const int) {
boost::serialization::base_object<B>(*this);
}
} ;
class D2 : public B {
public:
template < typename Ar > void serialize(Ar& ar, const int) {
boost::serialization::base_object<B>(*this);
}
virtual ~D2() {}
} ;
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT_KEY(B);
BOOST_CLASS_EXPORT_KEY(D1);
BOOST_CLASS_EXPORT_KEY(D2);
并且 hier.cpp
包含实现:
#include <boost/serialization/export.hpp>
#include "hier.h"
BOOST_CLASS_EXPORT_IMPLEMENT(D1);
BOOST_CLASS_EXPORT_IMPLEMENT(D2);
并且 main.cpp
使用序列化:
#include <iostream>
#include <sstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include "hier.h"
int main(int argc, char* argv[])
{
B* d1 = new D1();
B* d2 = new D2();
std::ostringstream os;
boost::archive::text_oarchive oa (os);
oa & d1 & d2;
}
编译没有任何问题,但运行它会导致:
terminate called after throwing an instance of 'boost::archive::archive_exception'
what(): unregistered class - derived class not registered or exported
这意味着派生类是未注册,意味着 hier.cpp
中的注册不起作用。但这确实很奇怪,因为:
如果我注册实现既是
main.cpp
又是hier.cpp
,它会在链接时发出重复的定义。 意味着hier.cpp
中的注册是可以的,并且暴露在链接器可见性中。,否则不会出现重复定义错误。如果我仅在
main.cpp
中注册实现,则运行正常。
在那种情况下我真的很困惑。如有任何意见和建议,我们将不胜感激。提前致谢。
I am using boost::serialization
in my project. The project is large, and serializes my objects in several places. According to the documentation here, I should export my class with two separated step.
BOOST_EXPORT_KEY()
in.h
file, witch contains the declaration.BOOST_EXPOET_IMPLEMENT()
in.cpp
file, witch contains the instantiation(definition) of the exporting.
hier.h
the class hierarchy, there are 3 classes in the hierarchy.
/*
B <---+--- D1
|
+--- D2
*/
#include <boost/serialization/base_object.hpp>
class B {
public:
virtual ~B() {}
template < typename Ar >
void serialize(Ar& ar, const int) {
}
} ;
class D1 : public B {
public:
virtual ~D1() {}
template < typename Ar > void serialize(Ar& ar, const int) {
boost::serialization::base_object<B>(*this);
}
} ;
class D2 : public B {
public:
template < typename Ar > void serialize(Ar& ar, const int) {
boost::serialization::base_object<B>(*this);
}
virtual ~D2() {}
} ;
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT_KEY(B);
BOOST_CLASS_EXPORT_KEY(D1);
BOOST_CLASS_EXPORT_KEY(D2);
And a hier.cpp
contains the implementation:
#include <boost/serialization/export.hpp>
#include "hier.h"
BOOST_CLASS_EXPORT_IMPLEMENT(D1);
BOOST_CLASS_EXPORT_IMPLEMENT(D2);
And a main.cpp
use the serialization:
#include <iostream>
#include <sstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include "hier.h"
int main(int argc, char* argv[])
{
B* d1 = new D1();
B* d2 = new D2();
std::ostringstream os;
boost::archive::text_oarchive oa (os);
oa & d1 & d2;
}
It compiled without any problem, but run it will cause:
terminate called after throwing an instance of 'boost::archive::archive_exception'
what(): unregistered class - derived class not registered or exported
Which means the derived class is not registered, means the registration in the hier.cpp
is not working. But that is really strange, because:
If I register implementation is both
main.cpp
andhier.cpp
, it issue duplicated definition while linking. Means the registration inhier.cpp
is OK and is exposed into the linkers visibility., otherwise there will be no duplicated definition error.If I register implementation only in
main.cpp
, it runs OK.
I am really confused in that situation. Any comment and suggestion is appreciated. Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在调用
BOOST_CLASS_EXPORT_*
之前,您应该包含要使用的存档。然后,宏为标头添加特定的序列化函数。这意味着您应该将
hier.cpp
中的代码更改为以下内容:hier.h
中的代码相应更改:来源:
Boost 序列化文档
PS:< br>
我不知道这是否能解决您的问题,但我认为这可能会造成一些麻烦。我认为值得一试。
Before calling
BOOST_CLASS_EXPORT_*
you should include the archives which you want to use. The maсro then adds specific serialize-functions for the headers.This means you should change your code in
hier.cpp
to the following:The code in
hier.h
changes accordingly:Sources:
Boost Serialization Documentation
PS:
I do not know if this is solving your problem, but I think it could be causing some trouble. I think it's worth a try.