如何在 C++ 中从 dll 实例化类?
How can I instantiate a class from a dll in C++?
我正在为插件开发人员编写一个API,以便他们可以通过我的API访问应用程序的SDK。我的 API 在头文件中提供了一个宏和抽象类*,插件开发人员必须包含该宏和抽象类*才能从抽象基类继承并实现必要的函数(*请参阅下面的代码(。
就手头问题的研究而言,我已经通读了许多MSDN和stackoverflow文章,发现这些文章最相关:
- COM/ATL 的东西
- 一篇 C# 文章,类似于我在C++中使用反射尝试执行的操作
- 这篇关于为什么C++没有反思的文章
- 以及大量类似标题的文章,询问从DLL调用函数
这个问题是关于获取继承的抽象类/接口的实例,您希望插件开发人员在创建.dll
文件时实现该实例。
也许我的方法不正确,我已经掉进了一个兔子洞,但是像反射和/或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" {
PLUGINEXPORT 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;
};
因此,插件开发人员可以使用以下方法快速创建插件:
插件的: 插件1.hpp
class plugin1: public baseplugin
{
public:
virtual void load();
virtual void unload();
// other useful plugin methods/vars
}
插件的:插件1.cpp
PLUGIN(plugin1) // This creates getPlugin() and erasePlugin()
void plugin1::load() {
// do stuff
}
void plugin1::unload() {
// do stuff
}
// other functions
现在我只剩下加载编码/构建API.dll
以加载插件 .dll 目录。这是我当前的代码,我意识到不知道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(); // THIS LINE WORKS, I GET A POINTER TO A SINGLETON
plugin1Singleton->load(); // THIS CRASHES!!!!
这里可能值得注意的是,使用plugin1.dll
代码构建API.dll
按预期工作。我现在正在测试/弄清楚如何在运行时加载插件类型。我已经验证我能够使用调试器获取指向单例的指针,但是在将其转换为抽象类后尝试运行 load 方法时崩溃: 0xC0000005: Access violation executing location 0x80B1CCDC
实现插件API的一个好方法是借助boost::d ll。它提供了一些有用的工具来实现插件机制。例如,插件中有工厂方法。
您的应用程序对插件中定义的具体类型一无所知。它唯一可以操作的是应用程序中定义的类。每个插件都需要提供一个工厂方法,该方法创建插件中定义的具体类型的实例,并返回指向应用程序中定义的抽象类的指针。Plugin1.dll
中定义如下:
baseplugin* PLUGINEXPORT create_plugin()
{
return new plugin1;
}
在您的应用程序中,您可以动态加载Plugin1.dll
,获取create_plugin
函数的地址并调用它以获取plugin1
类的实例作为指向baseplugin
抽象类的指针。
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- 如何在 C++ 中从 dll 实例化类?
- DLL 中的实例化类在 QT 的 LoadLibrary 中引发 127 错误
- 如果在 DLL/Lib 中定义了对象,是否可以在客户端中实例化对象?
- Java从DLL实例化C++类
- 类和函数模板实例化的Visual Studio dll导出问题
- 如何在c++ dll中实例化一个类,使它在函数调用之间保持内存
- 跨DLL边界的c++类实例化
- 跨DLL的c++成员函数显式模板实例化
- 为什么要使用静态字符缓冲区来实例化从DLL加载的C++类
- 从DLL实例化模板类