我正在尝试创建一个模块化游戏系统,我希望用户定义的类能够被序列化。为此,我放置了从多态基类派生的类。我在尝试在此类上实现序列化时遇到了麻烦。我不断收到未注册的类异常(运行时错误)。
这是一个最小的测试用例:
环境:windows 8.1 MSVC++ 12 (visual studio 2013)
parent_class.h -- 定义多态的parent_class类
#pragma once
#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/export.hpp>
class parent_class
{
protected:
friend boost::serialization::access;
template <typename Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(x) & BOOST_SERIALIZATION_NVP(y);
}
float x;
float y;
public:
explicit parent_class(float x, float y) : x(x), y(y) {}
// virtual deconstructor to make it polymorphic
virtual ~parent_class()
{
}
};
BOOST_CLASS_EXPORT(parent_class);
Main.cpp - .exe 中唯一的 .cpp
#include "parent_class.h"
#include <boost/archive/xml_oarchive.hpp>
#include <fstream>
#include <iostream>
#include <Windows.h>
typedef parent_class* addChildFun(float, float, float);
int main()
{
// acquire module
HMODULE module = LoadLibraryA("SerializationDLL.dll");
assert(module);
// acquire function ptr
FARPROC addChildRaw = GetProcAddress(module, "makeChild");
assert(addChildRaw);
addChildFun* addChildPtr = reinterpret_cast<addChildFun*>(addChildRaw);
// make polymorphic pointer
parent_class* child = addChildPtr(325.f, 214.f, 2.5f);
// INIT BOOST SERIALIZIZATION ARCHIVE
std::ofstream stream{ "file.txt" };
boost::archive::xml_oarchive arch{ stream };
try
{
arch << BOOST_SERIALIZATION_NVP(child);
}
catch (std::exception& e)
{
std::cout << e.what(); // prints "unregistered class - derived class not registered or exported
}
std::cin.get();
delete child;
}
最后是我的 child_class.cpp —— .dll 中唯一的 .cpp
#include <parent_class.h>
#include <boost/archive/xml_oarchive.hpp>
class child_class : public parent_class
{
friend boost::serialization::access;
public:
float z;
explicit child_class(float x, float y, float z)
: parent_class(x, y),
z(z)
{
}
template <typename Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & boost::serialization::make_nvp("owner", boost::serialization::base_object<parent_class>(*this));
ar & BOOST_SERIALIZATION_NVP(z);
}
virtual ~child_class() override
{
}
};
// export the class
BOOST_CLASS_EXPORT(child_class)
// yes I am using MSVC -- hence dllexport
extern "C" __declspec(dllexport) parent_class* makeChild(float x, float y, float z)
{
return new child_class(x, y, z);
}
所有代码都应该是不言自明的——如果您有任何问题,请随时发表评论。
抱歉,代码太多了——我真的没法删减。
最佳答案
好吧,经过千辛万苦,我找到了解决方案,就在两行代码中。
问题似乎是存储类的 GUID 与实现之间的关联的映射被定义了两次,因为它驻留在 .dll 和 .exe 都链接到的 .lib 文件中。显而易见的解决方案是使用 Boost.serialization 库的动态链接支持。
如何使用它是在每个使用序列化库的.cpp 文件的开头放置一个#define BOOST_SERIALIZATION_DYN_LINK 1
。这样,代码只被实例化一次,boost 就可以找到映射中的类。
关于c++ - Boost.serialization 未注册类异常与运行时链接共享库中定义的序列化类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29871285/