在 Linux 環境下,Qt Creator 內建完整工具鏈,開發與調用動態庫 (`.so`) 流程順暢。本文提供一個最小化完整範例:創建 C++ 動態庫專案、導出函數/類、編譯生成 `.so`,再創建 GUI 應用專案鏈接調用,涵蓋 `.pro` 配置、跨平台導出宏、外部符號解析等關鍵細節。
File → New Project → **Library** → **C++ Library** → 名稱 `zsz` → 完成。
# -------------------------------------------------
# Project created by QtCreator
# -------------------------------------------------
TARGET = zz
TEMPLATE = lib
CONFIG += plugin # 生成插件風格庫
DEPENDPATH += .
INCLUDEPATH += .
SOURCES += mylib.cpp
HEADERS += mylib.h
#ifndef MYLIB_H
#define MYLIB_H
// Windows: __declspec(dllexport/import)
// Linux/macOS: 符號默認可見,無需修飾
#ifdef Q_OS_WIN
# define MY_EXPORT __declspec(dllexport)
#else
# define MY_EXPORT
#endif
class MY_EXPORT MyLib {
public:
int myMax(int a, int b);
int add(int a, int b);
};
// C 鏈接自由函數,便於 C 調用或動態載入
extern "C" MY_EXPORT int diff(int a, int b);
#endif // MYLIB_H
注意:類方法若需導出,**類定義前**加 `MY_EXPORT`;`extern "C"` 防止 C++ 名字修飾,配合 `MY_EXPORT` 導出。
#include "mylib.h"
extern "C" MY_EXPORT int MyLib::myMax(int a, int b) {
return (a >= b) ? a : b;
}
extern "C" MY_EXPORT int MyLib::add(int a, int b) {
return a + b;
}
extern "C" MY_EXPORT int diff(int a, int b) {
return (a >= b) ? (a - b) : (b - a);
}
Build → Build Project `zsz` → 輸出目錄生成 `libzsz.so` (Linux) / `zsz.dll` (Windows)。
File → New Project → **Application (Qt)** → **Qt Widgets Application** → 名稱 `use_zsz`。
將 `zsz` 專案輸出目錄下的 `mylib.h` 與 `libzsz.so` 複製到 `use_zsz` 專案根目錄 (與 `.pro` 同級)。
# -------------------------------------------------
# Project created by QtCreator
# -------------------------------------------------
TARGET = use_zsz
TEMPLATE = app
QT += widgets svg # 按需添加模組
DEPENDPATH += .
INCLUDEPATH += . # 當前目錄含 mylib.h
# 鏈接動態庫:相對路徑指向複製的 .so
LIBS += -L. -lzsz # 等價於 LIBS += ./libzsz.so
SOURCES += main.cpp
HEADERS += mylib.h
關鍵:`-L.` 告訴鏈接器當前目錄搜尋庫,`-lzsz` 鏈接 `libzsz.so` (Linux 命名慣例 `lib` + 名稱 + `.so`)。
#include
#include
#include
#include "mylib.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QPushButton hello("Hello World! Dynamic Lib");
hello.resize(400, 200);
// 1. 類成員函數調用 (需庫導出類)
MyLib lib;
qDebug() << "Max(15, 9) =" << lib.myMax(15, 9); // 15
qDebug() << "Add(15, 9) =" << lib.add(15, 9); // 24
// 2. C 風格自由函數調用 (extern "C")
qDebug() << "Diff(15, 9) =" << diff(15, 9); // 6
hello.show();
return app.exec();
}
編譯鏈接成功不代表運行成功。Linux 動態鏈接器按順序搜尋:
| 方案 | 操作 | 優點 | 缺點 |
|---|---|---|---|
| rpath (推薦開發/部署) | `.pro` 加入 `QMAKE_LFLAGS += -Wl,-rpath,\\$$ORIGIN` | 相對執行檔路徑,免環境變量,安全 | 需鏈接器支援 |
| LD_LIBRARY_PATH | `export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH` | 臨時測試方便 | 污染環境,生產不推薦 |
| 系統目錄安裝 | `sudo cp libzsz.so /usr/local/lib && ldconfig` | 系統級可用 | 需 root,版本管理麻煩 |
Qt Creator 專案模式下,構建後在構建目錄運行通常自動設置 `LD_LIBRARY_PATH`,直接點擊 Run 即可。發布時請採用 `rpath` 或打包腳本設置環境。
掌握此流程,你就能在 Qt Creator 中輕鬆實現模組化開發:核心邏輯封裝為動態庫,UI 層輕量調用,支援熱更新、插件架構與跨語言調用 (C/Python 等調用 `extern "C"` 接口)。