ZC: 我這里創建的是 不依賴 Qt的 動態鏈接庫。
1、創建動態鏈接庫工程(工程名為 “SharedLibZ”)
Qt5 --> File... --> New File or Project ... --> 選擇 "Libraries"的"C++ Library" --> Type:"Shared Library"(靜態的話,選擇"Statically Linked Livrary"),填好工程名,選好工程存放的位置 --> 選擇編譯工具 --> 選擇需要的模塊(所有的"√"都去掉,這樣只需要C++庫,不依賴任何QT庫) --> 連續"Next",全部使用默認的值,直到最后"Finish"。
2、修改 創建好的工程內容
2.1、看到 "sharedlibz_global.h" 中,有一個 Q_DECL_EXPORT,明顯是導出函數要用的(類似Windows的DLL中的"__declspec(dllexport)")。其實 Q_DECL_EXPORT是在 "qcompilerdetection.h" 中定義的,"查找定義"之后看到 在Linux這種的定義是這樣的:
#define Q_DECL_EXPORT __attribute__((visibility("default")))
2.2、將 自動生成的文件"工程名_global.h"、"工程名.h"、"工程名.cpp"全部刪掉,創建自己的 h/cpp文件 並寫代碼。(需要使用 Q_DECL_EXPORT 的話,就自己定義)
3、做一個簡單的例子程序(動態庫,?.so文件):
3.1、dllMain.h
#ifndef DLLMAIN_H #define DLLMAIN_H #define Z_DECL_EXPORT __attribute__((visibility("default"))) Z_DECL_EXPORT void TestA(); extern "C" { Z_DECL_EXPORT void TestB(int _i, int _j); } #endif // DLLMAIN_H
3.2、dllMain.cpp
#include <stdio.h> void TestA() { printf("TestA()\n"); } extern "C" { void TestB(int _i, int _j) { printf("TestB() --> _i : %d, _j : %d\n", _i, _j); } }
ZC: 如果 要使用 “extern "C"”來修飾一個函數的時候,記得要在 聲明函數 和 實現函數 的地方都加上“extern "C"”。
3.3、
#-------------------------------------------------
#
# Project created by QtCreator 2016-04-29T10:28:30
#
#-------------------------------------------------
QT -= core gui #這里可以看到,它去掉了 Qt的相關庫 #如果不顯示的去掉它們的話,程序還是會依賴Qt庫
TARGET = SharedLibZ
TEMPLATE = lib
DEFINES += SHAREDLIBZ_LIBRARY
SOURCES += \
dllMain.cpp
HEADERS += \
dllMain.h
unix {
target.path = /usr/lib
INSTALLS += target
}
4、
5、調用 DLL(工程名為 “SharedLibCallZ”)
5.1、創建工程。"Non-Qt Project" 的 "Plain C++ Project"
5.2、pro 文件中添加一行:“LIBS += -L/home/Qt5_Projects/build-SharedLibZ-Desktop_Qt_5_3_GCC_32bit-Debug -lSharedLibZ”
ZC: 上面的 ?.so項目需要顯示的去掉Qt相關庫,貌似本工程不需要顯示的去除Qt庫...
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp
LIBS += -L/home/Qt5_Projects/build-SharedLibZ-Desktop_Qt_5_3_GCC_32bit-Debug -lSharedLibZ
include(deployment.pri)
qtcAddDeployment()
5.3、main.cpp
#include <iostream> using namespace std; #include "/home/Qt5_Projects/SharedLibZ/dllMain.h" int main() { cout << "Hello World!" << endl; TestA(); TestB(1, 300); return 0; }
6、
ZC: 這樣,一個 不依賴 Qt庫 的 Linux動態庫就做好了,使用它 也是沒有問題的。
7、遺留問題:
7.1、.so文件 的導出函數 的函數名 如何查看?(Windows下 有工具Depends)
7.2、有“extern "C"” 和 沒有“extern "C"”,導出函數的函數名 有何變化?
7.3、導出函數 一般不加 函數參數壓棧規則(__stdcall等)。是∵大家都是使用的 gcc的默認規則的原因?
7.4、編譯出來的 ?.so文件,必須放到指定的目錄 或者 將?.so文件所在目錄 加入環境變量。有任何優化的方案嗎?
8、
9、
