qt       windows            linux

dll          .dll                       .so

lib 对应 a    archiver的缩写 为静态库,是好多个.o合在一起,用于静态连接

dll 对应 so   share object 共享库      

lib文件:(依据编译器)    MSVC编译器是生成.lib 文件,文件名不变。 mingw编译器生成.a 文件,此外会在目标名称(即在.pro
文件中的TARGET)前面加lib

dll文件:(依据平台)   windows平台是.dll 文件,unix平台是.so  ,mac是.dylib

创建链接库

静态链接库

设计导出类,包括ui窗口类,对话框类。

在.pro文件中

TEMPLATE = lib
CONFIG += staticlib

TARGET = 

编译静态链接库时,不管是debug还是release版本,编译生成都是相同的文件名,并不会为debug版本自动添加一个字母“d”.

但是在debug或者release版本编译应用程序时,需要使用相应版本库文件。所有需要手动将debug版本的静态库更名,即在文件名后加上字母“d”,如
myStaticLib.lib => myStaticLibd.lib .

使用静态库方法是:

1.在应用程序的源程序目录下新建一个include文件夹,把.h头文件和.lib静态链接库文件都拷贝过去。

2.在项目管理目录树右键,选择“add library”,选择库类型“external
library”(即外部库),连接类型必须选择"static",因为是静态库。

 勾选add "d"suffix for debug version.使在debug模式下,应用程序自动调用debug版本的库文件。

共享库

1,共享库会多一个特殊的头文件 xxx_global.h。用来代替qt的宏 Q_DECL_EXPORT 和Q_DECL_IMPORT.

2.在定义的导出类名称前面多了在xxx_global.h定义过的宏,用于表明该类为导出类。

3,编译后会生成.dll文件和.lib文件。同样,不管是debug还是release版本,编译生成都是相同的文件名。

导出函数

直接在函数声明加上Q_DECL_EXPORT 表示导出函数。为了兼容不同mingw和msvc编译器,加上extern "C"
#if defined(TESTDLL_LIBRARY) # define TESTDLLSHARED_EXPORT Q_DECL_EXPORT #else
# define TESTDLLSHARED_EXPORT Q_DECL_IMPORT #endif extern "C" int
TESTDLLSHARED_EXPORT dev(int a, int b); int dev(int n1, int n2) { return n1 -
n2; } //在exe include 该头文件,然后直接调用
导出类

在声明类加上Q_DECL_EXPORT 即可。
#if defined(TESTDLL_LIBRARY) # define TESTDLLSHARED_EXPORT Q_DECL_EXPORT #else
# define TESTDLLSHARED_EXPORT Q_DECL_IMPORT #endif class TESTDLLSHARED_EXPORT
Testdll { public: Testdll(); int add(int n1,int n2); }; #include "testdll.h"
Testdll::Testdll() { } int Testdll::add(int n1, int n2) { return n1 + n2; }
//在exe中include该头文件,定义导出类的对象,然后调用相应的函数。
注意:其实对类的导出,一般都是父类纯虚函数的实现。这样可以在不同mingw和msvc编译器中相互调用。
class MSCVDLLSHARED_EXPORT test { public: virtual int add(int a,int b) = 0;
}; class test1 :public test { public: int add(int a,int b) override; }; extern
"C" MSCVDLLSHARED_EXPORT test* getInstance(); extern "C" MSCVDLLSHARED_EXPORT
void DeleteInstance(test*pInstance ); int test1::add(int a, int b) { return a +
b; } test *getInstance() { test *pInstance = new test1(); return pInstance; }
exe调用 test *ptest = getInstance(); int bb = ptest->add(1,4);
DeleteInstance(ptest); void DeleteInstance(test *pInstance) { if(pInstance)
delete pInstance; }

使用共享库

隐式链接

1.在源程序目录下新建一个include文件夹,把2个.h头文件(即包括_global.h文件)拷贝过去。

2..在源程序目录下新建一个lib文件夹,把 .lib或者是.a库文件都拷贝过去。

3.在项目管理目录树右键,选择“add library”,选择库类型“external
library”(即外部库),连接类型必须选择"dynamic",因为是动态库。在library file选中include目录下的.lib
或者.a文件作为库文件。

或者直接在.pro配置文件的LIBS +=添加上去。如 LIBS += $$PWD/lib/libPropertyBrowser.a  

4.必须将动态链接库文件.dll拷贝到可执行文件的的目录下,即pro 配置中的DESTDIR

显示链接

1.
显示链接通过QLibrary实现,一个QLibrary对象只能对一个共享库进行操作。一般在QLibrary构造函数中传递一个文件名,表示共享库文件。可以不用带后缀,因为可以通过平台自动识别。 

如 QLibrary myLib("DelphiDLL");
QLibrary
的load函数用于首动载入dll到内存,一般不需要手动调用,因为在dll的函数第一次被调用时QLibrary会自动调用此函数。isLoaded 判断dll
是否已经被载入内存,unload用于将dll从内存卸载。如果不调用卸载,那么只会在程序退出时才卸载。
一个动态链接库在内存只有一个实例,基石有多处调用了这个动态链接库里的函数,它也只是会被载入一次。

2 .声明函数原型类型
如 typedef int (*FunDef)(int); //函数原定定义
3. 使用QLibrary 的resolve函数解析需要调用的函数。
如 FunDef myTriple = (FunDef) myLib.resolve("triple"); //解析DLL中的函数
triple为在dll的函数名
4.调用函数
如 int V=myTriple(ui->spinInput->value()); //调用函数

注意事项

在windows系统上,mscv编译器的exe想调用mingw编译器的dll,需要在dll的导出函数或导出类声明为 extern "C" 如下:
dll 导出函数的声明及定义 extern "C" int MSCVDLLSHARED_EXPORT dev1(int a, int b); int
dev1(int a, int b) { return a - b; } 导出的lib和dll为:mscvdll.lib 和mscvdll.dll
exe的.pro配置文件 LIBS += $$PWD/lib/mscvdll.lib

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信