C++檔案說明及使用方法
C++檔案說明及使用方法
C++/C程式編譯的過程可以粗分為兩個階段:編譯和連結;編譯又可以分為 預處理、編譯、彙編三個階段
在編寫編譯C++的過程中有很多種檔案,例如原始檔,標頭檔案,靜態庫檔案,動態庫檔案等。每種型別的檔案都有其存在的意義
庫檔案
庫是一些函式和類的集合,其實現了某些特定的功能,是程式的開發免於從頭開始。
庫有兩種:靜態連結庫和動態連結庫!在windows下靜態連結庫為.lib,動態連結庫為.dll;Linux下靜態連結庫為.a,動態連結庫為.so。這裡我們只介紹Windows下的庫。
1. 特點
無論是靜態連結庫還是動態連結庫,都是庫檔案,是obj檔案的集合,都已經完成了編譯過程,它們的作用也是在經歷連結後生成可執行檔案。在我們的工程中,如果採用靜態連結庫(靜態編譯),工程在編譯時會匯出lib中的宣告和實現,並將所有程式碼都嵌入到宿主程式,生成最終的可執行檔案,釋出軟體時,只需要釋出exe檔案,不再需要.lib檔案;如果採用動態編譯庫(動態編譯),工程在編譯過程中只將庫中的宣告部分匯出,嵌入到程式碼中生成可執行檔案,再執行期間動態的去載入解除安裝.dll。釋出軟體時,由於可執行檔案的實現在dll中,所以dll必須與exe一起釋出。靜態連結庫不能再包含其它庫檔案,動態連結庫可以再包含其它庫檔案。
2.優缺點
靜態連結:佔用空間大,程式編譯完成後,移植性強;lib不能再包含其它庫,擴充套件性差;庫檔案升級時需要編譯整個工程,靈活性差。
動態連結:佔用空間小,庫方法更新只需要更換DLL,擴充套件性和靈活性強
3.靜態庫生成及使用方法
靜態連結庫生成方式:以建立test.lib為例
1.新建標頭檔案、原始檔
在建立的工程中,開啟解決方案資源管理器。在原始檔下建立test.cpp,標頭檔案下建立test.h,新增對應的程式碼。
2.配置屬性
在工程的屬性表中,修改配置屬性
- 常規->專案預設值->配置型別:將配置型別設定為靜態庫(.lib)
3.排除工程中的main.cpp(包含main函式的入口檔案),生成
靜態連結庫匯入方式:
在專案的屬性表中,附加庫目錄和包含目錄,新增依賴項
- C/C+±>常規->附加包含目錄:新增include目錄
- 連結器->常規->附加庫目錄:新增lib目錄
- 連結器->輸入->附加依賴項:新增 tinyxml.lib
4.動態庫生成及使用方法
DLL的分類有三種,Non-MFC DLL(非MFC DLL),MFC Regular(MFC規則DLL)和MFC Extension DLL(MFC擴充DLL)。
動態連結庫的生成方法:以Non-MFC DLL為例
1.新建一個應用程式型別為DLL的工程
開啟VS2015,新建一個VC++空專案,並將應用程式型別設定為DLL,如下:
工程建立好後,將平臺配置修改為Debug|X64
2.新增標頭檔案和原始檔
—在解決方案資源管理器中的標頭檔案下新增新專案test.h,程式碼如下—
#ifndef __TEST_H__
#define __TEST_H__
extern "C" int __declspec(dllexport) add(int num1, int num2);
#endif
標頭檔案中extern "C"是告訴編譯器該函式採用C呼叫方式進行編寫
__declspec(dllexport)是宣告函式add為dll的匯出函式,DLL的匯出函式是指可供呼叫dll的程式呼叫的函式;如果直接像靜態庫標頭檔案的呼叫方式:int add(int num1, int num2)
則是DLL的內部函式,DLL內部函式只能用於DLL自身呼叫,不能供呼叫DLL的函式呼叫。
—在解決方案資源管理器中的原始檔下新增新專案test.cpp,程式碼如下—
#include "test.h"
int add(int num1, int num2) {
return num1 + num2;
}
3.生成動態庫
右鍵解決方案下的TestDLL專案,生成。在工程(解決方案)的x64/Debug資料夾下生成了如下檔案,其中包含.lib和.dll
動態連結庫使用方法:
DLL檔案的呼叫方式有兩種,一種是顯式呼叫,一種是隱式呼叫。
—顯式呼叫—
1.在解決方案下新建一個控制檯應用專案,命名為TestUseDLL
2.呼叫函式
在TestUseDLL.cpp檔案中新增如下程式碼:
#include "stdafx.h"
#include "windows.h"
#include <iostream>
typedef int(*lpAddFun)(int num1, int num2);
int main()
{
HINSTANCE hDLL;
hDLL = LoadLibrary(L"TestDLL.dll");
if (hDLL != NULL) {
lpAddFun add = (lpAddFun)GetProcAddress(hDLL, "add");
if (add != NULL) {
int ret = add(4,5);
std::cout << ret << std::endl;
}
FreeLibrary(hDLL);
}
system("Pause");
return 0;
}
直接通過Windows自帶的LoadLibrary函式動態載入DLL模組,並將DLL模組控制程式碼賦給HINSTANCE控制程式碼物件,再通過Windows自帶的GetProcAddress函式得到DLL模組中指定函式名的函式指標,並賦值給函式指標add,使用add即可呼叫動態連結庫中的add。程式輸出如下:
—隱式呼叫—
1.將動態庫的標頭檔案,生成的lib檔案和dll檔案獨立打包,如下:
在新建一個控制檯應用專案,在專案的屬性表中,附加庫目錄和包含目錄,新增依賴項
- C/C+±>常規->附加包含目錄:新增include目錄
- 連結器->常規->附加庫目錄:新增lib目錄
- 連結器->輸入->附加依賴項:新增 TestDLL.lib
2.設定DLL
工程中DLL的搜尋順序依次為(禁用安全DLL查詢模式):
- 程式執行模組所在目錄
- 當前目錄(程式開啟的目錄)
- 系統目錄:\Windows\System32
- Windows目錄:\Windows
- 環境變數PATH中的目錄
DLL作為我們的資原始檔,一定需要被工程找到,我們通常將DLL與工程生成的可執行檔案.exe放在同一目錄,並一起釋出。
3.呼叫函式
在TestUseDLL.cpp檔案中新增如下程式碼:
#include "stdafx.h"
#include <iostream>
#include "test.h"
int main()
{
int ret = add(4, 5);
std::cout << ret << std::endl;
system("Pause");
return 0;
}
程式能夠正常輸出9
5.動態庫更新方法
這裡的更新有兩種:
1.單純實現方法的更新,標頭檔案未更新:直接替換DLL即可
2.增加新的方法,標頭檔案也更新:替換標頭檔案、.lib庫檔案以及.dll庫檔案
6.動態庫的跨語言使用
VS2015中匯入檔案說明
1.VC++目錄->包含目錄:新增include目錄
2.VC++目錄->庫目錄:新增lib目錄
3.C/C+±>常規->附加包含目錄:新增include目錄
4.連結器->常規->附加庫目錄:新增lib目錄
5.連結器->輸入->附加依賴項:新增 TestDLL.lib
上面的1和3都能將標頭檔案的include目錄加入到工程,但是區別在於,1中的包含目錄會修改系統的Include巨集的值,是全域性的,而3只針對當前專案,對其它專案沒有影響。2與4同理,2會影響全域性的庫,4只針對當前專案新增庫。5是使用的lib資料夾中的依賴項。
參考:
相關文章
- C/C++標頭檔案說明C++
- Qtum智慧合約使用方法及說明QT
- Linux常用目錄及檔案說明Linux
- Infer - 檔案說明
- 檔案-spfile說明
- C++ 中檔案流(fstream)的使用方法及示例C++
- fepk檔案格式說明
- linux和STL 常用標頭檔案及說明Linux
- Nginx的配置檔案說明Nginx
- Docker 的配置檔案說明Docker
- LINUX常用檔案說明Linux
- android混淆檔案說明Android
- 檔案-init.ora說明
- MySQL 日誌檔案 說明MySql
- Apache 配置檔案說明(轉)Apache
- Nginx配置檔案詳細說明Nginx
- linux日誌檔案說明Linux
- saltstack/saltmaster配置檔案說明(二)AST
- Redis配置檔案引數說明Redis
- oracle控制檔案轉儲說明Oracle
- Linux的基本檔案說明Linux
- django的初始化檔案說明Django
- http.conf配置檔案說明HTTP
- linux /etc/fstab檔案配置說明Linux
- web.xml檔案配置的說明WebXML
- CentOS8中systemd配置檔案說明CentOS
- oracle 資料檔案(Datafile ) 大小 限制 說明Oracle
- php檔案操作錯誤程式碼說明PHP
- Ubuntu修改Hosts檔案工具HostsTool使用說明Ubuntu
- Oracle 資料檔案 reuse 屬性 說明Oracle
- oracle日誌檔案頭轉儲說明Oracle
- oracle資料檔案頭轉儲說明Oracle
- Oracle密碼檔案的作用和說明Oracle密碼
- MongoDB資料檔案備份與恢復詳解及實驗說明MongoDB
- Oracle安裝光碟內容的檔案說明Oracle
- Hadoop之HDFS檔案讀寫流程說明Hadoop
- JDK安裝目錄中的檔案說明JDK
- DB2 Content Manager 配置檔案說明DB2