在VS2015中匯入/建立靜態庫並使用靜態庫【VS+Qt專案開發系列】
本專案示例原始碼已經上傳,歡迎點選下載~
注:靜態庫——在連結步驟中,聯結器將從庫檔案取得所需的程式碼,複製到生成的可執行檔案中,這種庫稱為靜態庫,其特點是可執行檔案中包含了庫程式碼的一份完整拷貝;缺點就是被多次使用就會有多份冗餘拷貝。即靜態庫中的指令都全部被直接包含在最終生成的 EXE 檔案中了。在vs中新建生成靜態庫的工程,編譯生成成功後,只產生一個.lib檔案。
解決方案資料夾目錄如下所示——我們接下來要講的靜態庫模組都是在圖中的Common資料夾下進行的, 如果對專案的文件架構不理解,可以先看這篇部落格【VS+Qt專案開發】(三)解決方案與專案文件架構設計
注:我的解決方案路徑是 C:\Users\Heylink\Documents\Visual Studio 2015\Projects\MySolution\
1. 直接匯入已有靜態庫
1.1 直接將已有的靜態庫專案拷貝到Common資料夾下,別忘了新增Output和Output\TempFile兩個資料夾用以存放輸出的相關檔案。
注:我這裡匯入的靜態庫名字叫“Common_VS2015”,是前輩們提供的封裝函式庫
1.2 在專案中匯入該靜態庫
step1:點選解決方案——>右鍵——>新增——>現有專案
step2:找到Common資料夾下的.sln檔案,點選“開啟”
step3:匯入成功!
OK!匯入成功啦!現在我們來看看如何自己建立靜態庫。
2. 自己建立靜態庫
什麼情況下需要自己建立靜態庫呢?一般是為了程式碼的解耦合以及模組化。我們需要將一些基本的方法進行封裝,方便自己以後在別的專案中使用或者提供給別的小夥伴使用。
2.1 解決方案——>右鍵——>新增——>新建專案——>Visual C++——>Win32專案
注:位置選擇解決方案中的Common資料夾下,名字命名為Common_VS2015
2.2 選擇靜態庫,預編譯頭和安全開發生命週期(SDL)檢查可要也可不要,我們這裡選擇不要
2.3 完成
2.4 新增相關檔案結構/include、/source、/Output、/Output/TempFile
/include:存放標頭檔案
/source:存放原始檔
/Output:存放輸出檔案
/Output/TempFile:存放中間輸出檔案
2.5 新增標頭檔案、原始檔
注:新增的時候位置要注意,標頭檔案選擇include資料夾,原始檔選擇source資料夾,新增完後原始檔中程式碼會報錯,因為分屬於不同資料夾,原始檔找不到標頭檔案位置。看步驟2.6
標頭檔案CommonLib.h
#pragma once
namespace heylink{
class CommonLib {
public:
CommonLib();
~CommonLib();
int add(int n, int m);
int minus(int n, int m);
};
}
原始檔CommonLib.cpp
#include "CommonLib.h"
namespace heylink{
CommonLib::CommonLib()
{
}
CommonLib::~CommonLib()
{
}
int CommonLib::add(int n, int m)
{
return n + m;
}
int CommonLib::minus(int n, int m)
{
return n - m;
}
}
2.6 配置標頭檔案路徑
Common_VS2015右鍵——>屬性——>C/C++常規;在附加包含目錄處填寫include資料夾名字即可
注:配置和平臺務必選擇所有配置、所有平臺
2.7 配置靜態庫常規屬性
Common_VS2015右鍵——>屬性——>配置屬性——>常規
主要修改以下三項配置:
- 輸出目錄:修改為$(SolutionDir)Common\$(ProjectName)\Output\$(Configuration)\
- 中間目錄:修改為$(SolutionDir)Common\$(ProjectName)\Output\TempFile\$(Configuration)\
- 目標檔名:修改為common即可
點選“應用”
2.8 生成靜態庫
Common_VS2015右鍵——>生成
配置為Debug模式
配置為Release模式
至此,靜態庫已經生成
3.靜態庫使用
3.1 檢查你的專案屬性是否正確
MySolution(主專案)右鍵——>屬性
注:為了能夠釋出32位與64位的安裝包,我們的配置最好都是設為面向所有配置+所有平臺
如果只有Win32或者x64,沒有所有平臺選項的話,點選右側的配置管理器,進行新建
3.2 將靜態庫原始碼的標頭檔案依賴進來,確保在編碼時就能夠使用而不報錯
新增靜態庫標頭檔案位置:$(SolutionDir)Common\Common_VS2015\include
注:上面的這個Common_VS2015要記得改為你自己的靜態庫專案的名稱
3.3 將靜態庫生成的lib檔案依賴進來,確保能在編譯期間使用
新增靜態庫lib所在的位置:$(SolutionDir)Common\Common_VS2015\Output\$(Configuration)\common.lib
如果你細心觀察,你會發現這個路徑就是我們之前配置的靜態庫專案的輸出目錄,沒錯,我們就是在這裡面去拿生成的lib檔案。還是那句話,注意把Common_VS2015改為你自己的靜態庫的名稱。
注意:從實際開發來看,選擇所有配置+所有平臺一般不會出問題,但是不排除還會出現以下錯誤
報錯:LINK : fatal error LNK1181: 無法開啟輸入檔案
“C:\Users\Heylink\Documents\VisualStudio 2015\Projects\MySolution\Common\Common_VS2015\Output\Release\\.obj”
出現該問題的情形是我在Release+x64的配置下生成主專案MySolution時碰到的,我看了一下配置
可以發現路徑最末尾少了common.lib,可是之前我的確是選擇所有配置+所有平臺的,所以還希望大家到時候再確認一下是否配置到位。
注意:每次新增完記得點選“應用”+“確定”
3.4 在專案中使用靜態庫
在前三步做完後,我們就可以在專案中使用靜態庫的類和函數了。
我在主專案中建立了一個簡單的計算器UI,部分程式碼如下所示:
MySolution.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_MySolution.h"
#include "CommonLib.h"
using namespace heylink;
class MySolution : public QMainWindow
{
Q_OBJECT
public:
MySolution(QWidget *parent = Q_NULLPTR);
~MySolution();
private:
CommonLib * m_commonLib; //靜態庫中的類
Ui::MySolutionClass ui;
private slots:
//槽函式,計算兩數之和
void calcSlot();
};
MySolution.cpp#include "MySolution.h"
MySolution::MySolution(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
m_commonLib = new CommonLib();
QObject::connect(ui.calcButton, SIGNAL(clicked()), this, SLOT(calcSlot()));
}
MySolution::~MySolution() {
delete m_commonLib;
}
void MySolution::calcSlot()
{
int firstvalue = ui.firstValue->text().toInt();//取出第一個文字轉化為整數型別
int secondvalue = ui.secondValue->text().toInt();
int resultvalue = m_commonLib->add(firstvalue, secondvalue);//呼叫靜態庫方法
ui.resultValue->setText(QString::number(resultvalue));
}
3.5 執行結果
注:如果是新建專案第一次執行,那麼出現如下錯誤
#include "ui_XXXXX.h" 出錯
提示:無法開啟原始檔“ui_*****.h”
解決方案:在UI檔案XXXXX.ui 上右鍵再點選編譯
然後就可以順利執行啦~
大功告成!
歡迎到我的GitHub主頁下載專案原始碼~