1. 程式人生 > >VS中C++靜態/動態庫檔案的編譯除錯與使用

VS中C++靜態/動態庫檔案的編譯除錯與使用

基礎知識:
不同語言之間可以通過呼叫動態連結庫 (dll)來呼叫別人寫好的函式
同一語言可以呼叫別人寫好的靜態(lib)庫

靜態連結庫:是通過靜態聯編的,在連結時link將自己的(.obj)二進位制檔案和別人的lib檔案一起共同生成.exe檔案。

靜態連結庫的缺點是:

1)比較吃記憶體
2)生成的exe檔案大
3)升級不方便

動態連結庫:是將自己生成的EXE程式和需要呼叫的DLL一起釋出

動態連結庫的特點

1)DLL和EXE分別釋出,更新互不影響
2)程式需要使用DLL中的函式時候載入進記憶體,不用時釋放
DLL預設查詢路徑:
1)首先,跟exe同文件夾目錄。
2)其次,C盤下System32系統目錄
3)再次,環境變數的Path路徑


編寫庫檔案

1》靜態庫檔案

首先,建立C++工程


其次,配置屬性(或者是在建立工程時,直接選擇靜態庫,則這裡不用再配置

在“屬性”->“配置屬性"->”常規“->”配置型別“下選擇”靜態庫(.lib)“(預設是"應用程式(.exe)")

最後,在工程檔案上右擊點選生成,在解決方案目錄下的Debug目錄下既可以找到生成的.lib檔案。


這裡需要強調的是:vs2013預設按照c++的命名規範進行編譯的。但是如果按照C++的命名規範生成的庫檔案只能被C++程式呼叫。

我們需要顯示的告訴編譯器按照c的規範進行編譯,這樣生成的函式就可以被c呼叫。

在函式的定義和宣告時,在函式頭加

extern "C"(例如:extern "C" int add(int a, int b)

2》動態庫檔案

首先,建立動態庫工。


其次,以C語言的動態連結庫匯出

[

例如:

#define DLL_API extern "C" _declspec(dllexport) //定義巨集 dllexport以動態庫匯出

DLL_API int add(int a, int b)
{
return a + b;
}

]

這裡需說明:

1、在“C++”下定義“C”函式,需要加extern “C”關鍵詞。用extern "C"來指明該函式使用C編譯方式。輸出的“C”函式可以從“C”程式碼裡呼叫

2、使用微軟專用的_declspec (dllexport)  
cpp檔案在編譯為OBJ檔案時要對函式進行重新命名,C語言會把函式name重新命名為_name,而C++會重新命名為

[email protected]@decoration,
extern "C"表示用C語言的格式將函式重新命名。要輸出整個的類,對類使用_declspec(_dllexpot);要輸出類的成員函式,則對該函式使用_declspec(_dllexport)

最後,生成動態庫檔案,在解決方案資料夾下的Debug目錄下會生成一個.lib和一個.dll檔案

庫檔案的使用

靜態庫檔案的提供者只需要提供:(1)標頭檔案、(2)編譯好的靜態庫檔案.lib

  • 呼叫別人寫好的lib庫:
一、先將標頭檔案加入自己的工程中
二、(最好將靜態庫檔案放在自己的工程下)

在專案名上右鍵--》屬性--》配置屬性--》VC++目錄--》庫目錄--》編輯(將庫檔案所在目錄進行錄入)

在專案名上右鍵--》屬性--》配置屬性--》連結器--》輸入--》附加依賴項--》(將庫檔名進行錄入)



或者是:在工程中:#pragma comment ( lib,"*.lib" )和在工程設定裡寫上鍊入*.lib的效果一樣,不過這種方法寫的程式別人在使用你的程式碼的時候就不用再設定工程settings了。這樣你就不用在project setting中linker的lib設定裡指定這個lib了。

三、至此,就可以使用靜態庫檔案中的函式進行程式設計。

  • 呼叫別人寫好的dll庫
方法一:(以靜態的方式呼叫)[配置與靜態庫呼叫類似]

1、將動態庫的標頭檔案、.dll、.lib檔案全部拷進自己的專案目錄中。

2、在專案中右擊新增動態庫中的標頭檔案。

3、在專案設定中

在專案名上右鍵--》屬性--》配置屬性--》VC++目錄--》庫目錄--》編輯(將動態庫檔案所在目錄進行錄入)

在專案名上右鍵--》屬性--》配置屬性--》連結器--》輸入--》附加依賴項--》(將動態庫檔名進行錄入)

lib檔案中放的是函式的呼叫介面

真正生成的二進位制檔案都在.dll中

4、至此便可以使用動態庫中的函數了。


方法二:動態呼叫

1、將動態連結庫.dll檔案放在當前專案資料夾中。

2、在自己專案的標頭檔案中[建立的是win32專案--》控制檯應用程式--》非空專案]新增:
#include "windows.h"  //使用函式和某些特殊變數

3、在自己專案的cpp檔案中:
typedef int(*ADD)(int a, int b);//定義一個函式指標
int main()
{

HINSTANCE hinstance=LoadLibrary(_T("DLLTest.dll"));//_T是vs中特定的巨集,在c++早期都是單位元組,_T(將單位元組換成雙位元組)是搜尋雙位元組函式
//返回控制代碼-->函式庫的首地址

ADD add = (ADD)GetProcAddress(hinstance, "add");

int res = add(4, 6);

FreeLibrary(hinstance);

return 0;
}

注意:

LoadLibrary函式利用一個名稱作為引數,獲得DLL的例項(HINSTANCE型別是例項的控制代碼),通常呼叫該函式後需要檢視一下函式返回是否成功,如果不成功則返回NULL(控制代碼無效),此時呼叫函式FreeLibrary釋放DLL獲得的記憶體。

GetProcAddress函式利用DLL的控制代碼和函式的名稱作為引數,返回相應的函式指標,同時必須使用強轉;判斷函式指標是否為NULL,如果是則呼叫函式FreeLibrary釋放DLL獲得的記憶體。此後,可以使用函式指標來呼叫實際的函式。
最後要記得使用FreeLibrary函式釋放記憶體。


動態連結庫的除錯

除錯dll:(一般為了除錯DLL,會自己寫一個應用程式[呼叫dll])
在DLL專案右鍵-->屬性-->配置屬性-->除錯-->命令-->瀏覽-->開啟(呼叫該DLL的應用程式)exe檔案

在DLL.cpp檔案中打斷點,點除錯即可


[

這裡需要注意,

在除錯時,將exe檔案拷貝到dll專案資料夾下
或者保證exe資料夾下沒有dll庫檔案(但是dll專案與exe專案在同一解決方案下)都可以
]



相關推薦

VSC++靜態/動態檔案編譯除錯使用

基礎知識:不同語言之間可以通過呼叫動態連結庫 (dll)來呼叫別人寫好的函式同一語言可以呼叫別人寫好的靜態(lib)庫靜態連結庫:是通過靜態聯編的,在連結時,link將自己的(.obj)二進位制檔案和別人的lib檔案一起共同生成.exe檔案。 靜態連結庫的缺點是: 1)比較

用Makefile編譯靜態檔案動態檔案

    最近要用到的簽名演算法只給了一堆原始碼沒有給庫檔案,api都不好呼叫,於是嘗試著用Makefile給一堆c原始碼編譯靜態連結庫檔案和動態連結庫檔案。 Makefile檔案編輯的相關資料連結: https://www.cnblogs.com/yya

VSc++檔案呼叫c 函式 ,fatal error C1853 預編譯標頭檔案來自編譯器的早期版本,或者預編譯頭為 C++ 而在 C 使用它(或相反)

出現錯誤:error C1853: “Debug\ConsoleApplication1.pch”預編譯標頭檔案來自編譯器的早期版本,或者預編譯頭為 C++ 而在 C 中使用它(或相反) 相關資料:

靜態連結編譯使用 linux下的動態連結靜態連結到底是個什麼鬼?(一)靜態連結編譯使用

linux下的動態連結庫和靜態連結庫到底是個什麼鬼?(一)靜態連結庫的編譯與使用       知識不等於技術,這句話真的是越工作的時間長越深有體會,學習到的知識只有不斷的實踐,才成真正在自已的心裡紮下根,成為自身的一部分,所以無論如何,我希望我的部落格可以

關於原始檔,標頭檔案,靜態連結檔案動態連結檔案的的理解

先從原始檔和標頭檔案的關係說起,由於是還是初學階段,只接觸了C++語言和windows平臺下的程式設計,所以只講這兩方面的東東, 標頭檔案的作用:對函式,變數,和類的宣告,其實在標頭檔案也可對一些特殊函式和變數定義,比如可以在標頭檔案中對行內函數和const型別變數定義,由於對類的宣告

原始檔,標頭檔案,靜態連結檔案動態連結檔案的的理解

如果你把一個.exe檔案只接放到沒有操作系充的“裸機”上去執行,顯然是執行不了的,可是你把這個程式放在一個裝有windows系統的電腦上就能運行了,顯然,程式的執行還是得依靠windows作業系統,這裡就要說到.dll檔案,上面說到的連結這一步時的程式碼複製只講到對程式作者自已寫的檔案和.lib檔案中用到的程

linux動態編譯和載入的查詢順序

Glibc安裝的庫中有一個名為ld-Linux.so.X其中X為一個數字(版本), 在不同的平臺上可以通過ldd檢視 $ldd /bin/cat linux-vdso.so.1 =>  (0x00007fff9176f000) libc.so.6 => /lib

Makefile 編譯動態檔案及連結動態

原文轉自 :http://www.cnblogs.com/ljtknowns/p/5647793.html 檔案目錄結構如下 1 dynamiclibapp.c 2 Makefile 3 comm/inc/apue.h 4 comm/errorhandle.c 5

VSC++的包含目錄、附加包含目錄和目錄和附加目錄的區別

文章轉自[VS中C++的包含目錄、附加包含目錄和庫目錄和附加庫目錄的區別],版權歸[TheOneGIS]所有 對Visual Studio中C++的包含目錄、附加包含目錄和庫目錄和附加庫目錄的區別不是很清楚,參考別人的文章整理出來的。供大家分享學習! Visual Studio C++工程中

MAC環境下 VS CodeC語言標頭檔案匯入錯誤

今天重新拾起了C語言,下載了vs code和CLion, 然後發現vs code寫好程式碼之後標頭檔案下方出現波浪線表示錯誤,百思不得其解。 然後看網上解答,找到了答案,好像是因為需要路徑設定 #include errors detected. Please update your

C/C++ 靜態連結(.a) 動態連結(.so)

平時我們寫程式都必須 include 很多標頭檔案,因為可以避免重複造輪子,軟體大廈可不是單靠一個人就能完成的。但是你是否知道引用的那些標頭檔案中的函式是怎麼被執行的呢?這就要牽扯到連結庫了! 庫有兩種,一種是 靜態連結庫,一種是 動態連結庫,不管是哪一種庫,要使用它們,都要在程式中包含相應的 includ

c++檢視動態函式地址

我們知道在生成動態庫時,如果使用.def檔案.那麼可以在.def中定義函式地址即例: add @1這種方式.但畢竟這是一種取巧的方式,如果你想獲得任何一個動態庫中函式地址,那麼我這邊可以提供兩個方法.(1)使用vs自帶的功能我用的是VS2005開啟工具選項,下面有Visual

vs安裝Easyx圖形(僅c++)

下載EasyX圖形庫,連結http://www.easyx.cn/downloads/ 手動安裝: a.將Include資料夾中的所有標頭檔案複製到VS2012的標頭檔案目錄中,為:自己安裝目錄

arm平臺Opencv靜態動態編譯

opencv 2.4.12移植到arm詳細教程 opencv2.4.12 ubuntu12.04 GCC 4.3.2 1.首先下載編譯器,解壓,設定環境變數,完成後,在終端輸入arm後按Tab鍵,若出現arm的相關的內容,則表示配置正確; 參考:htt

靜態-動態混合編譯

cc -g -o test_server main_server.o main_db.o err_me.o -Wl,-dn -L/usr/local/mysql/lib/ -l mysqlclient -Wl,-dy -lpthread -lm -ldl -lcrypt

包含目錄、目錄、附加包含目錄、附加目錄、附加依賴項如何使用? 及靜態動態的創建調用和vs裏引用的使用

pragma 經驗 dll blog res 編譯器 rdquo 編譯期 靜態 https://blog.csdn.net/Young__Fan/article/details/80528740 引言:vs中怎麽添加外部頭文件?如過直接在項目頭文件處,添加一下,如下

Java調用c程序動態詳細案例

mic fan 調用 c程序 案例 href java pid blank 1n閡嚎o指N階墑06灰tjhttp://huiyi.docin.com/arg9509 N19u4wTfnd塵2http://shufang.docin.com/fbqja96992 84稭棧

C# 調用 C++/CLI (托管模式c++) 的動態(DLL)

C++/CLI C# Dll調用 1.創建C++/CLI的動態庫 添加類 右鍵生成後即可生成 CLI_Dll.dll2.創建C#窗口應用程序,引用CLI_Dll.dll,然後就可以像是調用C#生成的的dll調用CLI_Dll.dll。C# 調用 C++/CLI (托管模式c++) 的動態庫(D

動態(.dll)的建立使用———VS編譯器實現

一、動態庫的概念 ①概念:動態庫連結時不復制,程式執行時由系統動態載入到記憶體,供程式呼叫。而且系統只加載一次,可以被多個程式共用。 ②特點: 動態函式庫在編譯的時候並沒有被編譯進目的碼中,需要用到相應的功能,程式碼才會被呼叫到程式中,節約記憶體 動態庫的改變,程式

h標頭檔案 lib檔案 dll動態檔案之間的關係

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!