【发布时间】:2009-10-04 13:59:26
【问题描述】:
如何从 dll(dll 中的构造函数)创建一些类?(C++) 或者如何从 dll 中动态加载类?
【问题讨论】:
-
你有匹配的头文件和/或库文件来访问 dll 吗?
-
是的,我有我的标题和来源
标签: c++ winapi constructor
如何从 dll(dll 中的构造函数)创建一些类?(C++) 或者如何从 dll 中动态加载类?
【问题讨论】:
标签: c++ winapi constructor
您需要在构建 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())。
【讨论】:
严格回答你的问题,你需要添加一个返回构造函数结果的extern "C" 函数:
extern "C" foo* __declspec(dllexport) new_foo(int x) {
return new foo(x);
}
然后在您的源代码中,您可以在“new_foo”上使用 GetProcAddr 来调用该函数。
【讨论】:
您需要从 DLL 中导出一个调用构造函数并返回新对象的函数。
尽量避免使用具体的 C++ 类型作为函数参数; DLL 的想法是您可以独立更新它们,但是升级后的编译器可能会以不同的方式布局 std::string,从而导致运行时不兼容。
这就是 COM 的根,例如 - 有限类型系统和用于获取对象实例的标准导出函数。
【讨论】:
除了使用 __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 导出表
freeSomClass(IPublicInterface*),只是为了确保内存被正确释放?