如何在C ++中从dll实例化一个类?

问题描述 投票:1回答:1

我正在为插件开发人员编写API,以便他们可以通过我的API访问应用程序的SDK。我的API在头文件中提供了一个宏和抽象类*,plugin-devs必须包含该宏和抽象类以从抽象基类继承并实现必要的功能(*请参见下面的代码)。

关于当前问题的研究,我已经阅读了许多MSDN和stackoverflow文章,并发现它们最相关:

此问题是关于您希望插件开发人员在创建其.dll文件时实现的继承的抽象类/接口的实例。

也许我的方法不正确,我已经陷入困境,但是像Reflections和/或COM这样的事情似乎应该做的事...只有COM对于此操作似乎显得过分了,因为应用程序将在客户端运行。关于C++/CLI Reflections的文章似乎很有希望,但我正在Visual Studio中使用C ++ 17。

在最高级别上,预期的行为是:

  1. [API.dll加载插件目录(例如plugin/plugin1.dllplugin/plugin2.dll
  2. [API.dll通过抽象类'getPlugin()]创建插件的单例实例>
  3. 调用由插件实现的其他方法,值得注意的是load()
  4. 因此,这是有关插件开发人员使用API​​的一些背景设置信息。该API为接口/抽象类的开发人员提供了标头,并提供了在宏中创建单例的方法。

API's:baseplugin.hpp

#ifdef BUILDINGAPI
#define PLUGINIMPORT 
#define PLUGINEXPORT  __declspec(dllimport)
#else
#define PLUGINIMPORT  __declspec(dllimport)
#define PLUGINEXPORT  __declspec(dllexport)
#endif

// Long macro defined here for creating/deleting singleton
#define PLUGIN(classType)                                           \
static std::shared_ptr<classType> singleton;                        \
extern "C" {                                                        \
    DLLIMPORT uintptr_t getPlugin()                                 \
    {                                                               \
        if(!singleton) {                                            \
            singleton = std::shared_ptr<classType>(new classType());\
        }                                                           \
        return reinterpret_cast<std::uintptr_t>(&singleton);        \
    }                                                               \
    PLUGINEXPORT void erasePlugin() {                               \
        if(singleton)                                               \
            singleton = nullptr;                                    \
      }                                                             \
}

// Abstract class defined here:

class PLUGINEXPORT baseplugin
{
public:
    virtual void load() = 0;
    virtual void unload() = 0;
};

因此,插件开发人员可以使用以下方法快速创建插件:

插件:plugin1.hpp

class plugin1: public baseplugin
{
public:
    virtual void load();
    virtual void unload();
// other useful plugin methods/vars
}

插件:plugin1.cpp

PLUGIN(plugin1) // This creates getPlugin() and erasePlugin()
void plugin1::load() {
// do stuff
}
void plugin1::unload() {
// do stuff
}
// other functions

现在我剩下的工作是加载编码/构建API.dll以加载插件.dlls的目录。这是我当前的代码,我意识到不知道RTTI是行不通的:

API's:dllmain.cpp

typedef uintptr_t(*pFunc)();
HINSTANCE hinstLib = LoadLibrary(TEXT("plugin1.dll"));
if (hinstLib != NULL) {
    FARPROC ProcAdd = GetProcAddress(hinstLib, "getPlugin"); // address to singeleton function
    // If the function address is valid, call the function.  
    if (NULL != ProcAdd) {
        pFunc pPluginSingleton = (pFunc) ProcAdd;
        baseplugin* plugin1Singleton = (baseplugin*) pPluginSingleton(); // hoping to cast to child class
        plugin1Singleton->load(); // hoping to call the child class' load method

在这里可能值得注意的是,使用API.dll的代码构建plugin1.dll的工作符合预期。我现在正在测试/弄清楚如何在运行时加载插件类型。

我正在为插件开发人员编写API,以便他们可以通过我的API访问应用程序的SDK。我的API在头文件中提供了一个宏和抽象类*,plugin-devs必须在头文件中将其包括到...

c++ dll dllimport
1个回答
0
投票
© www.soinside.com 2019 - 2024. All rights reserved.