快速包装DLL

最近初步研究了下windows下VS工程如何导出动态链接库,在此简单总结下。

配置属性»常规里将“配置类型”设为动态库(.dll)。

在包含导出函数定义的头文件中,加入如下宏定义。

 #ifdef DLL_EXPORTS
 #define DLL_API __declspec(dllexport)
 #else
 #define DLL_API __declspec(dllimport)
 #endif

对于每个想导出的函数,不妨称为函数A,B,C等,可将其写成:

 extern “C”{
       DLL_API  int    _cdecl A( int x, int y );
       DLL_API  char _cdecl B( const char *  a, int l );
       DLL_API  bool _cdecl C( float m, float n );
 }

相应地,这些函数实现头部也要在相同位置加上DLL_API_cdecl(目前只用这个调用协议哈),但不用加上extern "C"

C/C++»预处理器里添加预处理器定义DLL_EXPORTS,这个相当于在整个项目所有文件开头加上:

  #define DLL_EXPORTS

这样做的话,DLL_API就可以控制这里的函数是导出还是导入。在编译期,由于定义了DLL_EXPORTS,函数被导出;在需要被链接时,函数也可以被导入。

DLL原本只是设计为导出函数的,在DLL出现后才有C++的面向对象,因此DLL导出类有点不方便。这里只提及使用类中函数的情况。

对于每个要导出的类,需要稍稍改变其结构。我们可以特意为之构造一个父类,使导出类继承之,其所有需要导出的函数均标为virtual。父类必须有虚析构函数,构造函数则不必。父类定义的所有虚函数均需为空定义,或返回恰当的无效值。

父类定义好后,导出一个函数,其返回类型为父类实例的指针,但函数内部则new一个导出类作为返回值。同时,在头文件为导出的函数提供一个函数指针,供调用者使用。

我大概查了下这种虚函数做法的原理,似乎是因为虚函数和静态变量在初始化时都能直接放到类所在的内存空间中,所以能被调用。

显式调用时,只需要使用前面生成的动态链接库和相同的头文件即可。

原文由博主发布于逸仙时空BBS。

你可能感兴趣的:(dll)