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

  • 相关阅读:
    Hard Rock
    Codeforces Round #416 (Div. 2) B. Vladik and Complicated Book
    codeforces 793B. Igor and his way to work
    codeforces 1B Spreadsheets
    HDU 1069 Monkey and Banana
    codeforces 2B The least round way
    【机器学习】 通俗说拟合
    python-八皇后问题
    python-核心知识思维导图
    python-@property 属性
  • 原文地址:https://www.cnblogs.com/sggggr/p/13467853.html
Copyright © 2011-2022 走看看