• Qt添加链接库总结


    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文件,而是和工程所在目录同级的,因此一定要记清楚。

  • 相关阅读:
    BZOJ_4034 [HAOI2015]树上操作 【树链剖分dfs序+线段树】
    SPOJ QTree【树链剖分】
    BZOJ_1503 [NOI2004]郁闷的出纳员 【Splay树】
    Hibernate学习实例
    Educational Codeforces Round 64 C. Match Points 【二分思想】
    ramn 备份操作
    表值函数--自定义工作日历
    删除win10开始菜单中程序的目录
    C#自定义注释自动生成模板注释
    oralce知识第三章
  • 原文地址:https://www.cnblogs.com/sggggr/p/13467853.html
Copyright © 2020-2023  润新知