使用Qt创建动态和静态链接库

一、创建静态链接库点击打开链接


静态链接库是将函数和数据编译成的一个二进制文件,Linux下的静态链接库是*.a文件,而在Windows下的静态链接库是*.LIB文件。编译器在连接的时候会恢复静态库文件中的函数和数据,并将它们和应用程序中的其它模块组合在一起生成可执行文件,因此,体积比较大。


在Qt中创建静态库文件的主要步骤如下:
1、新建一个创建C++库文件项目;
2、构建项目,生成库文件;
3、配置环境变量;

首先新建一个创建C++库文件项目,如下如所示:

使用Qt创建动态和静态链接库


项目源代码如下:
[cpp] view plain copy
  1. //staticlibrary.h  
  2. #ifndef STATICLIBRARY_H  
  3. #define STATICLIBRARY_H  
  4.   
  5. #include <QDialog>  
  6. class QPushButton;  
  7.   
  8. class StaticLibrary : public QDialog {  
  9.     Q_OBJECT  
  10. public:  
  11.     StaticLibrary(QWidget *parent = 0);  
  12. private:  
  13.     QPushButton *button;  
  14. };  
  15.   
  16. #endif // STATICLIBRARY_H  
[cpp] view plain copy
  1. //staticlibrary.cpp  
  2. #include "staticlibrary.h"  
  3. #include <QtGui>  
  4.   
  5. StaticLibrary::StaticLibrary(QWidget *parent) : QDialog(parent)  
  6. {  
  7.     setWindowTitle(tr("My Static Library"));  
  8.     button = new QPushButton(tr("staticLibrary"));  
  9.     QHBoxLayout *layout = new QHBoxLayout;  
  10.     layout->addWidget(button);  
  11.     setLayout(layout);  
  12. }  

然后构建项目之后,会在目录的debug下生成一个后缀名为.a的文件(我是在Windows7上操作的,编译器版本为MinGW):
使用Qt创建动态和静态链接库

这个文件即为静态链接库文件了。接下来使用这个静态链接库文件。

创建一个新的Qt GUI项目,源码如下
[cpp] view plain copy
  1. //textlibrary.h  
  2. #ifndef TEXTLIBRARY_H  
  3. #define TEXTLIBRARY_H  
  4.   
  5. #include <QtGui/QDialog>  
  6. class QPushButton;  
  7.   
  8. class TextLibrary : public QDialog  
  9. {  
  10.     Q_OBJECT  
  11.       
  12. public:  
  13.     TextLibrary(QWidget *parent = 0);  
  14.     ~TextLibrary();  
  15.   
  16. private:  
  17.     QPushButton *button;  
  18. private slots:  
  19.     void on_button_clicked();  
  20. };  
  21.   
  22. #endif // TEXTLIBRARY_H  
[cpp] view plain copy
  1. //textlibrary.cpp  
  2. #include "textlibrary.h"  
  3. #include "mylib.h"  
  4. #include "staticlibrary.h"  
  5. #include <QtGui>  
  6.   
  7. TextLibrary::TextLibrary(QWidget *parent)  
  8.     : QDialog(parent)  
  9. {  
  10.     button = new QPushButton(tr("test"));  
  11.     setWindowTitle(tr("Test Library"));  
  12.     QHBoxLayout *layout = new QHBoxLayout;  
  13.     layout->addWidget(button);  
  14.     setLayout(layout);  
  15.   
  16.     connect(button, SIGNAL(clicked()), this, SLOT(on_button_clicked()));  
  17. }  
  18.   
  19. TextLibrary::~TextLibrary()  
  20. {  
  21.       
  22. }  
  23.   
  24. void TextLibrary::on_button_clicked()  
  25. {  
  26.     StaticLibrary w;  
  27.     w.show();  
  28.     w.exec();  
  29. }  
[cpp] view plain copy
  1. //main.cpp  
  2. #include <QtGui/QApplication>  
  3. #include "textlibrary.h"  
  4.   
  5. int main(int argc, char *argv[])  
  6. {  
  7.     QApplication a(argc, argv);  
  8.     TextLibrary w;  
  9.     w.show();  
  10.       
  11.     return a.exec();  
  12. }  

现在就要将前面创建的库文件使用到这个项目中了,在.pro文件中添加.a文件的路径,以及头文件的路径。
[cpp] view plain copy
  1. LIBS    += F:\library\staticLibrary\debug\libstaticLibrary.a  
  2. INCLUDEPATH += F:\library\staticLibrary  

运行结果如下:
使用Qt创建动态和静态链接库

其中右图为左图按钮test的效果。

二、创建动态链接库文件


动态链接库文件是在运行的时候被应用程序使用。在使用动态链接库的时候,一般需要提供两个文件:
1.引入库文件(.lib):引入库文件与静态链接库文件的后缀名相同,但是并不相同。引入库文件主要包含了DLL文件导出的函数和变量的符号名。
2.DLL(.dll):包含实际的函数和数据。

在使用动态链接库的情况下,在编译链接可执行文件时,只需要引入库文件即可,但是在运行可执行程序时,则需要加载相应的DLL文件。


接下来使用Qt创建动态链接库文件,步骤与创建静态库文件类似。源代码如下:

[cpp] view plain copy
  1. //mylib.h  
  2. #ifndef MYLIB_H  
  3. #define MYLIB_H  
  4.   
  5. #include "myLib_global.h"  
  6. #include <QDialog>  
  7. class QPushButton;  
  8.   
  9. class MYLIBSHARED_EXPORT MyLib : public QDialog {  
  10. public:  
  11.     MyLib(QWidget *parent = 0);  
  12. private:  
  13.     QPushButton *button;  
  14. };  
  15.   
  16. #endif // MYLIB_H  
[cpp] view plain copy
  1. //mylib.cpp  
  2. #include "mylib.h"  
  3. #include <QtGui>  
  4.   
  5. MyLib::MyLib(QWidget *parent) : QDialog(parent)  
  6. {  
  7.     setWindowTitle(tr("My Lib"));  
  8.     button = new QPushButton(tr("mylib"));  
  9.     QHBoxLayout *layout = new QHBoxLayout;  
  10.     layout->addWidget(button);  
  11.     setLayout(layout);  
  12. }  


然后配置环境变量,在.pro中添加:

[cpp] view plain copy
  1. LIBS    += F:\library\myLib\debug\myLib.dll  #这是编译期的链接库路径  
  2. INCLUDEPATH += F:\library\myLib  


在运行的时候,你可能得不到任何的结果。这是因为,虽然我们在LIBS中添加了dll文件的路径,但是这里的添加路径编译器时的查找路径,在运行时并不是从这里查找,而是先从当前项目目录中先找,然后从系统变量path的路径中去找。因此,有两种方法可以解决这个问题,将dll文件拷贝到当前目录中,或者在系统变量path中添加dll的路径,然后重启电脑。然后运行结果如下:

使用Qt创建动态和静态链接库

前面说到,动态链接库包括两个文件,引入库文件和DLL文件,为什么这里只需要将DLL文件拷贝到当前目录下呢?这是因为引入库文件中包含的是DLL文件的函数和变量的符号名,用来供给应用程序的编译通过,而在.pro文件中配置LIBS的路径即为编译阶段的查找路径,因此这里的引入库文件就不需要拷贝即可在编译阶段被编译器查找得到。