在哪里放置BOOST_CLASS_EXPORT为boost :: serialization? [英] Where to put BOOST_CLASS_EXPORT for boost::serialization?

查看:648
本文介绍了在哪里放置BOOST_CLASS_EXPORT为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 宏启用。


  1. p> EXPORT_IN_MAIN 可以工作,但不是我想要的。调用序列化的代码不需要知道PIMPL类的实现细节。


  2. EXPORT_IN_OBJECT 编译,但不工作:它导致一个 boost :: archive :: archive_exception 与消息 unregistered void cast 。根据文档,这应该通过序列化基础来解决使用 boost :: serialization :: base_object 的类,像我一样,但它不帮助。


  3. 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.

  1. 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.

  2. EXPORT_IN_OBJECT compiles, but does not work: it results in a boost::archive::archive_exception with the message unregistered void cast. According to the documentation, this should be solved by serializing base classes using boost::serialization::base_object, like I did, but it doesn't help.

  3. EXPORT_IN_HEADER does not even compile. The macro BOOST_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 a multiple 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆