1. 程式人生 > >使用Qt建立動態和靜態連結庫

使用Qt建立動態和靜態連結庫

一、建立靜態連結庫

靜態連結庫是將函式和資料編譯成的一個二進位制檔案,Linux下的靜態連結庫是*.a檔案,而在Windows下的靜態連結庫是*.LIB檔案。編譯器在連線的時候會恢復靜態庫檔案中的函式和資料,並將它們和應用程式中的其它模組組合在一起生成可執行檔案,因此,體積比較大。
在Qt中建立靜態庫檔案的主要步驟如下:
1、新建一個建立C++庫檔案專案; 2、構建專案,生成庫檔案; 3、配置環境變數;

首先新建一個建立C++庫檔案專案,如下如所示:


專案原始碼如下:
//staticlibrary.h
#ifndef STATICLIBRARY_H
#define STATICLIBRARY_H

#include <QDialog>
class QPushButton;

class StaticLibrary : public QDialog {
    Q_OBJECT
public:
    StaticLibrary(QWidget *parent = 0);
private:
    QPushButton *button;
};

#endif // STATICLIBRARY_H
//staticlibrary.cpp
#include "staticlibrary.h"
#include <QtGui>

StaticLibrary::StaticLibrary(QWidget *parent) : QDialog(parent)
{
    setWindowTitle(tr("My Static Library"));
    button = new QPushButton(tr("staticLibrary"));
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(button);
    setLayout(layout);
}
然後構建專案之後,會在目錄的debug下生成一個字尾名為.a的檔案(我是在Windows7上操作的,編譯器版本為MinGW):

這個檔案即為靜態連結庫檔案了。接下來使用這個靜態連結庫檔案。 建立一個新的Qt GUI專案,原始碼如下
//textlibrary.h
#ifndef TEXTLIBRARY_H
#define TEXTLIBRARY_H

#include <QtGui/QDialog>
class QPushButton;

class TextLibrary : public QDialog
{
    Q_OBJECT
    
public:
    TextLibrary(QWidget *parent = 0);
    ~TextLibrary();

private:
    QPushButton *button;
private slots:
    void on_button_clicked();
};

#endif // TEXTLIBRARY_H
//textlibrary.cpp
#include "textlibrary.h"
#include "mylib.h"
#include "staticlibrary.h"
#include <QtGui>

TextLibrary::TextLibrary(QWidget *parent)
    : QDialog(parent)
{
    button = new QPushButton(tr("test"));
    setWindowTitle(tr("Test Library"));
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(button);
    setLayout(layout);

    connect(button, SIGNAL(clicked()), this, SLOT(on_button_clicked()));
}

TextLibrary::~TextLibrary()
{
    
}

void TextLibrary::on_button_clicked()
{
    StaticLibrary w;
    w.show();
    w.exec();
}
//main.cpp
#include <QtGui/QApplication>
#include "textlibrary.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    TextLibrary w;
    w.show();
    
    return a.exec();
}
現在就要將前面建立的庫檔案使用到這個專案中了,在.pro檔案中新增.a檔案的路徑,以及標頭檔案的路徑。
LIBS    += F:\library\staticLibrary\debug\libstaticLibrary.a
INCLUDEPATH += F:\library\staticLibrary
執行結果如下:

其中右圖為左圖按鈕test的效果。

二、建立動態連結庫檔案

動態連結庫檔案是在執行的時候被應用程式使用。在使用動態連結庫的時候,一般需要提供兩個檔案:
1.引入庫檔案(.lib):引入庫檔案與靜態連結庫檔案的字尾名相同,但是並不相同。引入庫檔案主要包含了DLL檔案匯出的函式和變數的符號名。 2.DLL(.dll):包含實際的函式和資料。

在使用動態連結庫的情況下,在編譯連結可執行檔案時,只需要引入庫檔案即可,但是在執行可執行程式時,則需要載入相應的DLL檔案。

接下來使用Qt建立動態連結庫檔案,步驟與建立靜態庫檔案類似。原始碼如下:
//mylib.h
#ifndef MYLIB_H
#define MYLIB_H

#include "myLib_global.h"
#include <QDialog>
class QPushButton;

class MYLIBSHARED_EXPORT MyLib : public QDialog {
public:
    MyLib(QWidget *parent = 0);
private:
    QPushButton *button;
};

#endif // MYLIB_H
//mylib.cpp
#include "mylib.h"
#include <QtGui>

MyLib::MyLib(QWidget *parent) : QDialog(parent)
{
    setWindowTitle(tr("My Lib"));
    button = new QPushButton(tr("mylib"));
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(button);
    setLayout(layout);
}

然後配置環境變數,在.pro中新增:

LIBS    += F:\library\myLib\debug\myLib.dll  #這是編譯期的連結庫路徑
INCLUDEPATH += F:\library\myLib

在執行的時候,你可能得不到任何的結果。這是因為,雖然我們在LIBS中添加了dll檔案的路徑,但是這裡的新增路徑編譯器時的查詢路徑,在執行時並不是從這裡查詢,而是先從當前專案目錄中先找,然後從系統變數path的路徑中去找。因此,有兩種方法可以解決這個問題,將dll檔案拷貝到當前目錄中,或者在系統變數path中新增dll的路徑,然後重啟電腦。然後執行結果如下:



前面說到,動態連結庫包括兩個檔案,引入庫檔案和DLL檔案,為什麼這裡只需要將DLL檔案拷貝到當前目錄下呢?這是因為引入庫檔案中包含的是DLL檔案的函式和變數的符號名,用來供給應用程式的編譯通過,而在.pro檔案中配置LIBS的路徑即為編譯階段的查詢路徑,因此這裡的引入庫檔案就不需要拷貝即可在編譯階段被編譯器查詢得到。