将类的序列化放入DLL中 [英] Put the serialization of a class into a DLL

查看:241
本文介绍了将类的序列化放入DLL中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一个(工作)的例子来外部序列化DLL中的类结构。目前我无法找到任何示例。 Boost文档只是说明一些宏,论坛和新闻组正在讨论他们的解决方案的具体问题。



所以我要求一个例子(外部)序列化类结构如下。除了类代码,我添加了一些我的序列化代码(不起作用,见底部的错误消息)。

  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_;
};

所有到目前为止我都是这样的代码:



serializeFoo.h

  #ifndef _SERIALIZE_FOO_H_ 
#define _SERIALIZE_FOO_H_

#includeFoo.h
#include< boost / serialization / split_free.hpp>
#include< boost / serialization / version.hpp>

命名空间boost {
命名空间序列化{

模板< typename存档>
void save(Archive& ar,const Foo& object,const unsigned int version)
{
ar < object.getNumber();
}

模板< typename存档>
void load(Archive& ar,Foo& object,const unsigned int version)
{
int number;
ar>>数;
object.setNumber(number);
}

}} //命名空间括号

BOOST_SERIALIZATION_SPLIT_FREE(Foo)

#include #include< boost / archive / text_iarchive.hpp>
#include< boost / serialization / export.hpp>
BOOST_CLASS_EXPORT_KEY(Foo)

#endif // _ SERIALIZE_FOO_H_

serializeFoo.cpp

  #includeserializeFoo.h
BOOST_CLASS_EXPORT_IMPLEMENT(Foo)

serializeBar.h

  #ifndef _SERIALIZE_BAR_H_ 
#define _SERIALIZE_BAR_H_

#includeBar.h
#include< boost / serialization / split_free.hpp>
#include< boost / serialization / version.hpp>

命名空间boost {
命名空间序列化{

template< typename Archive>
void save(Archive& ar,const Bar& object,const unsigned int version)
{
ar < base_object<富>(对象);
ar<< object.getDouble();
}

模板< typename存档>
void load(Archive& ar,Bar& object,const unsigned int version)
{
double doubleNumber;
ar>> doubleNumber;
object.setDouble(doubleNumber);
}

}} //命名空间括号

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

  #includeserializeBar.h
BOOST_CLASS_EXPORT_IMPLEMENT(Bar)

序列化代码进入一个DLL,应该在另一个使用类Foo和Bar的项目中使用。一切编译都很好,但在运行时我收到消息

未注册的类派生类未注册或导出



那么我使用错误的宏?我想错过一个宏吗?上面的代码是正确的还是有某种结构性错误?也许这可能对很多其他人也是有用的,我不认为将类的序列化放入DLL是非常异国情调的。

解决方案

最近我遇到了类似的问题,3年后问了这个问题。我终于找到了解决办法。在上面的例子中。




  • Bar Foo ,因此必须注册/导出;

  • serializeFoo.cpp 实例化一个GUID模板类注册/导出 Foo ;

  • serializeBar.cpp 实例化一个GUID模板要注册/导出的类 Bar ;

  • 在导出类密钥之前,包含所有必需的归档类型的规则得到尊重;

  • 两个翻译单元链接在一起以创建一个DLL。



我假设在你的exe中,而你试图串行一个指向 Bar 对象的 Foo * 指针,你得到了未注册的类blahblah错误。这是因为Boost.Serialization不正确地在调用序列化函数之前 c> < >

我不知道为什么会发生这种情况,但是似乎GUID是以懒惰的方式生成的 - 如果翻译单元中没有符号 serializeBar.cpp 被使用,将不会执行在该翻译单元中定义的实例化/初始化代码 - 包括 Bar 的类注册/导出。 p>

为了证明这一点,您可以尝试在 serializeBar.cpp 中使用(虚拟)符号(例如通过调用虚拟在 Foo * 之前调用任何序列化函数之前,在 serializeBar.cpp 中实现的函数)。这个问题应该消失。



希望有帮助。


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;
  • The rules to include all necessary archive types before exporting the class keys are respected;
  • Both translation units are linked together to create a DLL.

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 (e.g. by calling a dummy function implemented in serializeBar.cpp) before calling any serialization function for Foo*. The issue should disappear.

Hope it helps.

这篇关于将类的序列化放入DLL中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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