如何在 C++ 中从 dll(dll 中的构造函数)创建一些类?

Posted

技术标签:

【中文标题】如何在 C++ 中从 dll(dll 中的构造函数)创建一些类?【英文标题】:How to create some class from dll(constructor in dll) in C++? 【发布时间】:2009-10-04 13:59:26 【问题描述】:

如何从 dll(dll 中的构造函数)创建一些类?(C++) 或者如何从 dll 中动态加载类?

【问题讨论】:

你有匹配的头文件和/或库文件来访问 dll 吗? 是的,我有我的标题和来源 【参考方案1】:

您需要在构建 DLL 时使用 __declspec(dllexport) 关键字声明您的类。使用DLL时,需要用__declspec(dllimport)声明类:

#ifdef COMPILING_DLL
#define DECLSPEC_CLASS __declspec(dllexport)
#else
#define DECLSPEC_CLASS __declspec(dllimport)
#endif

class DECLSPEC_CLASS MyClass

...

当 DLL 被编译时,你应该将 -DCOMPILING_DLL 添加到定义列表中。

使用类时,必须静态链接DLL,即将导入库mydll.lib传递给主程序。

如果你想在运行时加载 DLL,你需要在 DLL 中有一个 C 函数来创建一个对象并为你返回它。无法在 DLL 中动态查找构造函数(使用 GetProcAddress())。

【讨论】:

你能引用最后一句话的来源吗? AFAIK 演员有一个错误的名称,您可以使用该名称调用 GetProcAddress。什么会阻止你?【参考方案2】:

严格回答你的问题,你需要添加一个返回构造函数结果的extern "C" 函数:

extern "C" foo* __declspec(dllexport) new_foo(int x) 
    return new foo(x);

然后在您的源代码中,您可以在“new_foo”上使用 GetProcAddr 来调用该函数。

【讨论】:

【参考方案3】:

您需要从 DLL 中导出一个调用构造函数并返回新对象的函数。

尽量避免使用具体的 C++ 类型作为函数参数; DLL 的想法是您可以独立更新它们,但是升级后的编译器可能会以不同的方式布局 std::string,从而导致运行时不兼容。

这就是 COM 的根,例如 - 有限类型系统和用于获取对象实例的标准导出函数。

【讨论】:

Tt 听起来好像 DLL 的源不在他的控制之下。 DLL 源在我的控制之下 如果打算使用该类,那么它可能已经用 __declspec(dllexport) 编译了,所以只需说服头文件将 __declspec(dllimport) 放入类定义。如果没有,你可以随时自己修改头文件。【参考方案4】:

除了使用 __declspec 导出类的每个方法,您还可以依赖编译器可以通过 vtable 调用虚函数这一事实,例如:

//note: no __declspec
class IPublicInterface

  virtual ~IPublicInterface() = 0;
  virtual void SomeMethod() = 0;
;

//note: no __declspec
class SomeClass : IPublicInterface

  virtual ~SomeClass()  ... 
  virtual void SomeMethod()  ... 
;

//note: this is the only method which needs to be exported from the DLL
IPublicInterface* createSomeClass()

  return new SomeClass();

【讨论】:

接口/工厂模式很好,特别是如果您要使用GetProcAddress 并手动管理 .def 导出表 既然内存是在DLL中分配的,也许还应该有一个freeSomClass(IPublicInterface*),只是为了确保内存被正确释放? 我认为这个答案是错误的,应该删除。您不能跨插件边界传递多态对象,除非在插件和应用程序中使用完全相同的编译器。

以上是关于如何在 C++ 中从 dll(dll 中的构造函数)创建一些类?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C#/Python 中从 DLL 调用函数

我们如何在 C# 中从 C++ DLL 中获取所有方法?

在运行时加载 C++ DLL

在 C# 中从 C++ .DLL 加载值始终返回 true

在 Visual Studio 6 中从 VB 调用 VS2010 C++ dll

如何初始化堆,以便常规 MFC dll 中的静态构造函数可以使用它?