从DLL导出C ++类
我的大多数C / C ++开发都涉及整体模块文件,并且绝对没有类,因此通常当我需要使用可访问函数制作DLL时,我只是使用标准的__declspec(dllexport)指令将其导出。然后通过LoadLibrary()动态访问它们,或者在编译时使用头文件和lib文件访问它们。
当我们要导出整个类(及其所有公共方法和属性)时,该怎么做?
是否可以在运行时动态加载该类,如果可以,怎么办?
我们将如何使用标头和lib进行编译时链接?
解决方案
回答
我使用一些宏来标记要导入或者导出的代码
#ifdef ISDLL #define DLL __declspec(dllexport) #endif #ifdef USEDLL #define DLL __declspec(dllimport) #endif
然后在头文件中声明该类:
class DLL MyClassToExport { ... }
然后在库中包含#define ISDLL
和USEDLL`,然后将头文件包含在我们要使用该类的位置。
我不知道我们是否需要对LoadLibrary
进行其他操作
回答
当我们构建DLL和将使用DLL的模块时,请使用某种#define来区分彼此,然后可以在类头文件中执行以下操作:
#if defined( BUILD_DLL ) #define IMPORT_EXPORT __declspec(dllexport) #else #define IMPORT_EXPORT __declspec(dllimport) #endif class IMPORT_EXPORT MyClass { ... };
编辑:crashmstr击败了我!
回答
What about late-binding? As in loading it with LoadLibrary() and GetProcAddress() ? I'm used being able to load the library at run time and it would be great if you could do that here.
因此,有两种加载DLL的方法。第一种是引用DLL中的一个或者多个符号(例如,类名),提供适当的import .LIB,然后让链接程序找出所有内容。
第二个是通过LoadLibrary显式加载DLL。
两种方法都适用于C级函数导出。我们可以让链接程序处理它,也可以如我们所说的那样调用GetProcAddress。
但是,对于导出的类,通常仅使用第一种方法,即隐式链接到DLL。在这种情况下,DLL是在应用程序启动时加载的,如果找不到该DLL,则应用程序将无法加载。
如果要链接到DLL中定义的类,并且希望在程序启动后的某个时间动态加载该DLL,则有两个选择:
- 使用特殊的工厂函数创建该类的对象,该函数在内部必须使用(一小部分)汇编器将新创建的对象"连接"到其适当的偏移量。显然,这必须在DLL被加载之后的运行时完成。在这里可以找到有关此方法的很好的解释。
- 使用延迟加载DLL。
考虑到所有问题,最好只使用隐式链接,在这种情况下,我们肯定要使用上面显示的预处理器技术。实际上,如果我们在Visual Studio中创建一个新的DLL并选择"导出符号"选项,则将为我们创建这些宏。
祝你好运...
回答
如果愿意将vtable放在要导出的类中,则可以导出一个函数,该函数返回一个接口并在.dll中实现该类,然后将其放在.def文件中。我们可能需要做一些声明技巧,但是应该不要太难。
就像COM。 :)