我在使用带有动态库的谷物(Windows)上遇到问题。我已经阅读了谷物网站上的文档。但是,所有文档和示例都隐式链接DLL,而我需要能够显式链接我的DLL。我做了一个示例项目,向您展示我的设置以及我遇到的问题。
该项目分为三个项目,2个DLL和一个可执行文件。第一个DLL(Object.dll)包含一个名为Object的Base类。此DLL隐式链接到第二个DLL(Script.dll),它实现了一个名为Script的Derived类。然后,此DLL显式链接到可执行文件(Main.exe)。
Object.dll:
Object.h
#pragma once
class __declspec(dllexport) Object
{
public:
Object();
virtual ~Object();
int so;
virtual void foo() = 0;
template<class Archive>
void serialize(Archive& ar)
{
ar(so);
}
};
Object.cpp为空,所以我省略了它。
Script.dll:
Script.h
#pragma once
#include "Object.h"
class Script : public Object
{
public:
Script();
~Script();
void foo() override;
template<class Archive>
void serialize(Archive& ar)
{
ar(cereal::base_class<Object>(this));
}
};
Script.cpp
#include "Script.h"
Script::Script()
{
}
Script::~Script()
{
}
void Script::foo()
{
}
extern "C" __declspec(dllexport) Object* CreateObject()
{
return new Script();
}
extern "C" __declspec(dllexport) void DeleteObject(Object* obj)
{
delete obj;
obj = nullptr;
}
MAIN.EXE
#include "Object.h"
#include "Windows.h"
#include "cereal/archives/xml.hpp"
#include "cereal/types/memory.hpp"
typedef Object* (__cdecl *CREATEFUNCTION)();
typedef void(__cdecl *DELTEFUNCTION)(Object*);
using namespace std;
int main()
{
std::string dll("DLL.dll");
HINSTANCE dllHandle = LoadLibraryA(dll.c_str());
if (dllHandle == nullptr)
{
cout << "Couldn't load the DLL of the script " << endl;
return 1;
}
CREATEFUNCTION CreateObject = reinterpret_cast<CREATEFUNCTION>(GetProcAddress(dllHandle, "CreateObject"));
if (CreateObject == nullptr)
{
cout << "Couldn't load the CreateObject() function" << endl;
return 1;
}
DELTEFUNCTION DeleteObject = reinterpret_cast<DELTEFUNCTION>(GetProcAddress(dllHandle, "DeleteObject"));
if (DeleteObject == nullptr)
{
cout << "Couldn't load the DeleteObject() function" << endl;
return 1;
}
std::shared_ptr<Object> obj = std::shared_ptr<Object>(CreateObject(), DeleteObject);
cereal::XMLOutputArchive oAr(std::cout);
oAr(obj);
return 0;
}
当然,它抛出异常UNREGISTERED_POLYMORPHIC_EXCEPTION,因为我没有注册我的Script类。这也是我的问题,根据我所读到的,我应该将宏CEREAL_REGISTER_DYNAMIC_INIT添加到我调用CEREAL_REGISTER_TYPE的源文件中,这将是Script.h文件,因为我无法将其添加到源文件中多态性文档。我还应该将CEREAL_FORCE_DYNAMIC_INIT添加到主应用程序中包含的标头中,但我不在任何地方包含Script.h文件。
我试图将每个宏放在不同的地方(不包括在main.exe中),但我没有让它工作。有没有人知道这两个函数应该去哪里,以便我可以注册我的Script类并调用它的序列化函数?