从DLL导出C ++类

时间:2020-03-05 18:43:17  来源:igfitidea点击:

我的大多数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。 :)