显式链接DLL会导致异常

时间:2017-10-10 15:04:21

标签: c++ dll cereal

我在使用带有动态库的谷物(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类并调用它的序列化函数?

0 个答案:

没有答案