我正在为插件开发人员编写API,以便他们可以通过我的API访问应用程序的SDK。我的API在头文件中提供了一个宏和抽象类*,plugin-devs必须包含该宏和抽象类以从抽象基类继承并实现必要的功能(*请参见下面的代码)。
关于当前问题的研究,我已经阅读了许多MSDN和stackoverflow文章,并发现它们最相关:
此问题是关于您希望插件开发人员在创建其.dll
文件时实现的继承的抽象类/接口的实例。
也许我的方法不正确,我已经陷入困境,但是像Reflections和/或COM这样的事情似乎应该做的事...只有COM对于此操作似乎显得过分了,因为应用程序将在客户端运行。关于C++/CLI Reflections的文章似乎很有希望,但我正在Visual Studio中使用C ++ 17。
在最高级别上,预期的行为是:
API.dll
加载插件目录(例如plugin/plugin1.dll
和plugin/plugin2.dll
)API.dll
通过抽象类'getPlugin()
]创建插件的单例实例>load()
因此,这是有关插件开发人员使用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必须在头文件中将其包括到...