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

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

【问题讨论】:

  • 你有匹配的头文件和/或库文件来访问 dll 吗?
  • 是的,我有我的标题和来源

标签: c++ winapi constructor


【解决方案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*),只是为了确保内存被正确释放?
    • 我认为这个答案是错误的,应该删除。您不能跨插件边界传递多态对象,除非在插件和应用程序中使用完全相同的编译器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多