Qt添加链接库总结
一 前言:
在Qt工程开发过程中,经常会碰到集成第三方库的情况,不论是静态库还是动态库。由于Qt本身不完善等特性,集成过程中经常会出现各种各样的问题。针对遇到过的问题记录如下备忘,同时也希望能为更多开发者朋友提供前车之鉴。
二 基础知识简介:
2.1关于lib和dll的区别如下:
(1)lib是编译时用到的,dll是运行时用到的。如果要完成源代码的编译,只需要 lib;如果要使动态链接的程序运行起来,只需要dll。
(2)如果有dll文件,那么lib一般是一些索引信息,记录了dll中函数的入口和位 置,dll中是函数的具体内容;如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。使用静态编译的lib文件,在运行程序时 不需要再挂动态库,缺点是导致应用程序比较大,而且失去了动态库的灵活性,发布新版本时要发布新的应用程序才行。
(3)动态链接的情况下,有两个 文件:一个是LIB文件,一个是DLL文件。LIB包含被DLL导出的函数名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到DLL 文件。在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中相应函数代码的地址,从而节省了内存资源。DLL和LIB文件必须随应用程序 一起发行,否则应用程序会产生错误。如果不想用lib文件或者没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress装载。
三 加载方式:
3.1链接的两种方式
转:
显示调用
(该方式只使适用只有dll文件的例子,在此情况下,dll实现的函数名及参数应该是已知的)
Qt提供了一个 QLibrary 类供显示调用。下面给出一个完整的例子:
#include #include #include #include #include “dll.h” //引入头文件 typedef int (*Fun)(int,int); //定义函数指针,以备调用 int main(int argc,char **argv) { QApplication app(argc,argv); QLibrary mylib(“myDLL.dll”); //声明所用到的dll文件 int result; if (mylib.load()) //判断是否正确加载 { QMessageBox::information(NULL,“OK”,“DLL load is OK!”); Fun open=(Fun)mylib.resolve(“add”); //援引 add() 函数 if (open) //是否成功连接上 add() 函数 { QMessageBox::information(NULL,“OK”,“Link to Function is OK!”); result=open(5,6); //这里函数指针调用dll中的 add() 函数 qDebug()<<result; } else QMessageBox::information(NULL,“NO”,“Linke to Function is not OK!!!”); } else QMessageBox::information(NULL,“NO”,“DLL is not loaded!”); return 0; //加载失败则退出
myDLL.dll为自定义的dll文件,将其复制到程序的输出目录下就可以调用。显然,显示调用代码书写量巨大,实在不方便。
隐式调用
这个时候我们需要三个文件,头文件(.h)、导入库文件(.lib)、动态链接库(.dll),具体步骤如下:
1、首先我们把 .h 与 .lib/.a 文件复制到程序当前目录下,然后再把dll文件复制到程序的输出目录,
2、下面我们在pro文件中,添加 .lib 文件的位置: LIBS+= -L D:/hitempt/api/ -l myDLL
-L 参数指定 .lib/.a 文件的位置
-l 参数指定导入库文件名(不要加扩展名)
另外,导入库文件的路径中,反斜杠用的是向右倾斜的
3、在程序中include头文件(我试验用的dll是用C写的,因此要用 extern “C” { #include “dll.h” } )
下面是隐式调用的实例代码:
#include #include extern “C” //由于是C版的dll文件,在C++中引入其头文件要加extern “C” {},注意 { #include “dll.h” } int main(int argv ,char **argv) { QApplication app(argv,argv); HelloWordl(); //调用Win32 API 弹出helloworld对话框 qDebug()<<add(5,6); // dll 中我自己写的一个加法函数 return 0; //完成使命后,直接退出,不让它进入事件循环 }
3.2lib地址在pro文件中的写法
网友提供了一下这种方法,其中相当有借鉴之处。但我用后发现却编译失败(Qt5.6.1 Qt creator4.5.1),主要原因在与:lib文件的地址必须使用相对地址,而不是绝对地址,将一下地址改为:
LIBS += -L…/与工程目录同级的、放置lib的文件夹名/ -l后面紧跟lib文件名
就通过了。
在.pro文件中,加上一句话,告诉工程,.lib在哪里
LIBS += -LE:/project/QT/usbcan_info/ -lControlCAN
下面对这句话进行解析:
1)+=这个符号是连接在一起的,不要自做聪明,给分开了,写成+ = ,这样就是错的!
2)+=的左右两边可以有空格,也可以没有空格,随意的
3)-L之后紧接着就跟着.lib文件所在的目录,比如,我的目录是在E盘下的project目录下的QT目录下的usbcan_info下,注意,是紧跟着,不要分开,分开就错啦!
4)-l后面跟着的是.lib的文件名,注意,比如你的.lib文件时ControlCAN.lib,不要傻乎乎的写成了-lControlCAN.lib,不要带后缀,要写成-lControlCAN,同样,-l后面也没有空格
3.3关于相对目录的问题
在上一点中提到的相对目录的表示,例如-L …/debug/ ,debug不是当前工程所处的文件夹下的debug文件,而是和工程所在目录同级的,因此一定要记清楚。