不说导出那几种方式了,一般我们自己的工程只要一种就行:
extern "C" _API IExport* CreateExportObj();
其中加不加 __stdcall __cdecl 都行。如果要给别人用就一般用 __stdcall。
命名更改规律一图搞定:
再来说说dll导出类。
一般只要类前面加上 _API就行了,定义如下:
#ifdef MYDLL // MYDLL 是dll工程定义的,app工程不定义 #define _API __declspec(dllexport) #else #define _API __declspec(dllimport) #endif class _API myClass { public: int func(void){return 0;} private: int i; }
这样在app中引入lib和h就跟调用本地cpp一样方便。
但是,这里容易出问题,出来一个叫dll hell,就是dll地狱问题。这个问题的现象就是,你改动了这个dll,如果app没有重新编译容易崩溃!原因很多人都讲了可以看下:https://blog.csdn.net/qwertyupoiuytr/article/details/53999586
那么如何避免更改dll容易崩溃的问题呢?这不是违背只更换dll就可以更新这个初衷了吗?
方法1、
使用虚函数(多态性。java是仿照c++,不是c++仿照java)导出方法,并且定义2个单独的函数来创建和销毁该类:
#ifdef MYDLL #define _API __declspec(dllexport) #else #define _API __declspec(dllimport) #endif class _API ExportInterface { public: virtual void foo() = 0; }; // 定义单独函数初始化实例,也可以单例模式 extern "C" DLL_API ExportInterface* getInstance();
#define MYDLL #include "dllExample.h" // 该函数是示例,实际最好要做成单例模式,防止多次new,单例用法参考: // https://labisart.com/blog/index.php/Home/Index/article/aid/227 extern "C" DLL_API ExportInterface* getInstance() { ExportInterface* pInstance = new ExportClass(); return pInstance; }
具体实现的子类定义如下:
class ExportClass: public ExportInterface { pirvate: std::string x; //由于外部代码对此不可见,此处的std::string是安全的。 public: void foo(); //函数体在dllExample.cpp中实现 };
使用的时候,只要 getInstance()->foo()就可以调用了类的函数。
虚函数其实也有弊端,如果修改的dll,改变了虚函数原来的顺序,那么调用也会出问题。
方法2、
在接口不变的情况下,使用 extern "C"是一个方法,
方法3、
做成插件。只要接口不变,类怎么折腾都不会引起dll hell问题!
方法4、
导出类情况下,把private隐藏起来,做成一个指针,具体可以参考Qt的D指针方法,例如:
class Myclass{ public : int api(){return m_a;} private: int m_a; }; // 把m_a隐藏起来 class MyclassPrivate; class Myclass{ public : int api(); private: // 只维护一个私有指针 MyclassPrivate *pri; }; // cpp定义: class MyclassPrivate{ int m_a; }; Myclass(){ // 分配自己的内部私有数据 pri = new MyclassPrivate; } int Myclass::api() { return pri->m_a; }
QT调用dll也比较简单:
typedef CoreFrame* ( *icoreFrameInit)(QWidget *); QLibrary core("CoreFramed2.dll"); frame = (icoreFrameInit)core.resolve("coreFrameInit");
参考:
https://www.cnblogs.com/dongsheng/p/3924287.html
https://blog.csdn.net/xiaominggunchuqu/article/details/72837760
https://www.cnblogs.com/JingJ/p/4442286.html
https://blog.csdn.net/qwertyupoiuytr/article/details/53999586
https://blog.csdn.net/amnes1a/article/details/69055858