QT中靜態庫的產生與使用

來源:互聯網
上載者:User

標籤:

一. 靜態庫的產生
    1. 測試目錄: lib
    2. 源碼檔案名稱: mywindow.h, mywindow.cpp, 類MyWindow繼承於QPushButton, 並將文字設定為"I‘m in class MyWindow";
    3. 編寫專案檔: mywindow.pro
       注意兩點:
       TEMPLATE = lib
       CONFIG   += staticlib
    4. 產生Makefile:
       qmake
    5. 編譯產生靜態庫libmywindow.a
       make

二. 靜態庫的使用
    1. 測試目錄: test
    2. 將mywindow.h與libmywindow.a拷貝至test目錄下
    3. 編寫main.cpp, 包含標頭檔mywindow.h, 並調用MyWindow類
    4. 編寫專案檔: test.pro
       注意加上庫路徑與庫檔案名稱:
       LIBS += -L ./ -lmywindow
    5. 產生Makefile: qmake
    6. 編譯: make
    7. 運行: ./test

QT中共用庫的產生與使用

如果你開啟一些 Windows 應用程式的目錄,你會發現有很多程式的 exe 檔案都很小,大約幾百K 的樣子,並且目錄中不僅僅只有一個 exe 檔案,還包含著一大堆 dll 檔案。這些 dll 其實就是一些共用庫,所謂共用庫,其實就是一些動態連結程式庫,能夠由程式在運行時進行動態載入的庫。既然說是共用,那就是說,這些庫不僅僅自己的程式可以使 用,並且其他程式也可以使用,例如某些通用演算法。如果你發布一下自己編寫的 Qt 程式,也會看到很多系統的共用庫,就是那些 QtGui.dll 之類的東西。或許你會說,我寫的程式沒有同其他應用共用的庫,就不需要這些了吧!其實不然。因為共用庫的一個好處是可以動態載入,也就是說,如果你需要升 級程式,那麼就要簡單的替換掉這個 dll 就好了,不需要要求使用者重新安裝全部檔案。當然,這些 dll 也是有缺點的:動態載入的東西肯定會比靜態編譯的東西效率低一些。不過在現在的硬體環境下,這點效能損失已經可以忽略不計了。

今天我們要說的就是如何用 Qt 建立共用庫代碼。

我們還是使用 QtCreator。在建立工程的時候,我們選擇下面的 C++ Library 一項,然後點擊 OK。

在接下來的對話方塊中,有一個下拉式清單,分別是 Shared Library(共用庫),Statically Linked Library(靜態連結庫)和 Qt 4 Plugin(Qt 4 外掛程式)。我們選擇第一個共用庫,後面的步驟中會要求選擇加入哪幾個 Qt 模組,和前面一樣,選擇自己需要的部分,最後完成工程的建立。

我們會看到 QtCreator 已經幫我們建立好了一些檔案。其中有一個 {projectName}_global.h 的檔案是 QtCreator 替我們建立的。下面我們就從這個 {projectName}_global.h 開始:

 1 #ifndef LIB_GLOBAL_H  
2  #define LIB_GLOBAL_H
3
4 #include <QtCore/qglobal.h>
5
6 #if defined(LIB_LIBRARY)
7 # define LIBSHARED_EXPORT Q_DECL_EXPORT
8 #else
9 # define LIBSHARED_EXPORT Q_DECL_IMPORT
10 #endif
11
12 #endif // LIB_GLOBAL_H

這個檔案中只是定義了兩個宏 LIBSHARED_EXPORT,注意這裡的 LIB 就是我的工程名字。如果定義了 LIB_LIBRARY,LIBSHARED_EXPORT 定義為 Q_DECL_EXPORT,否則定義為 Q_DECL_IMPORT。看這個名字,就知道這就是把對象匯出的語句了。下面我們來編寫一個視窗(如果你希望這麼做,不要忘記在建立工程時勾選 QtGui 模組,預設是不勾選的):

lib.h

 1 #ifndef LIB_H  
2  #define LIB_H
3
4 #include <QMainWindow>
5
6 #include "lib_global.h"
7
8  class LIBSHARED_EXPORT MainWindow : public QMainWindow {
9  public:
10 MainWindow(QWidget *parent = 0);
11 };
12
13 #endif // LIB_H

lib.cpp

1 #include "lib.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 }

代碼很簡單,就是建立一個 MainWindow。同前面的代碼唯一不同的是,在標頭檔中,使用了 LIBSHARED_EXPORT 這個宏。你可以簡單的把它理解成,我需要把這個類 MainWindow 匯出。所謂匯出,就是將其編譯成一個 dll 檔案之後,其他的類可以使用這個匯出類。好了,下面和原來一樣,編譯一下這個工程。在 debug 檔案夾下你得到的是一個 lib.DLL 檔案和 liblib.a。後者是 Linux 下使用的庫,這裡不再詳述。

好了,我們要去使用這個 dll 了。建立另外一個工程,需要吧 .pro 檔案修改一下:

1 TARGET = test  
2 TEMPLATE = app
3
4 SOURCES += main.cpp
5
6 INCLUDEPATH += ../
7
8 LIBS += ../debug/lib.dll

首先,我們添加了 INCLUDEPATH 這一行。這一行就是為了讓我們的 test 項目可以找到 lib.h 和 lib_global.h 這兩個檔案,你需要把這裡的路徑替換成符合你的工程的路徑。LIBS 這一行則需要告訴編譯器(注意,這裡是編譯器!)到哪裡去找到這個 dll 檔案。然後我們編寫 main.cpp:

 1 #include <QtGui/QApplication>  
2 #include "lib.h"
3
4 int main(int argc, char *argv[])
5 {
6 QApplication a(argc, argv);
7 MainWindow w;
8 w.show();
9 return a.exec();
10 }

注意,我們使用了 lib.h,但是這個檔案並沒有在 HEADERS 裡面聲明,Qt 實際上就是從 INCLUDEPATH 這裡去找到這個檔案。MainWindow 在建立的 test 工程中並沒有聲明,那麼它在哪裡呢?當然就是在我們編譯出來的 lib.dll 裡面啦!我們知道,在連結的時候編譯器需要找到實現入口,也就是必須定位到這個 dll,這就是由這個 LIBS 指定的地方。

最後編譯運行一下這個 exe 檔案,怎麼樣?哦,如果你照我說的做了的話,你應該得到一個錯誤:找不到 lib.dll。怎麼會找不到呢?不是使用 LIBS 指定了嗎?請注意,我們強調了,這個指定是編譯期的。dll 是動態連結程式庫,也就是說,在 exe 啟動並執行時候需要找到這個庫。運行時尋找的順序是:當前路徑 -> 系統路徑(通常是 system32)。所以,要把我們先前產生的這個 lib.dll 複製到 exe 所在目錄,然後直接雙擊一下這個 exe 檔案。一個視窗出來了!有什麼區別嗎?運行起來是沒有區別的,但是我們知道,這個視窗是在這個 dll 裡面實現的!我們想往視窗裡面加個按鈕?沒問題,那就加吧!加完之後重新編譯一個新的 dll,複製到 exe 檔案夾覆蓋舊的,修改就完成啦!我們不需要修改這個 exe 了。

這個時候我們再來回憶一下,我們使用自己建立的 dll 的時候,是不是就和使用 QtGui.dll 一樣呢?只不過QtGui.dll 已經放在了庫目錄下, 不需要手動修改 .pro 檔案添加 INCLUDEPATH 和 LIBS 罷了。

QT中靜態庫的產生與使用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.