動態鏈接庫(c++)


我的微信公眾平台:AIT111666888

動態鏈接庫通常都不能直接運行,也不能接收消息。它們是一些獨立的文件,其中包含能被可執行程序或其它DLL調用來完成某項工作的函數。只有在其它模塊調用動態鏈接庫中的函數時,它才發揮作用。

 

Windows API中的所有函數都包含在DLL中。其中有3個最重要的DLL,Kernel32.dll,它包含用於管理內存、進程和線程的各個函數;User32.dll,它包含用於執行用戶界面任務(如窗口的創建和消息的傳送)的各個函數;GDI32.dll,它包含用於畫圖和顯示文本的各個函數。

 

靜態庫:函數和數據被編譯進一個二進制文件(通常擴展名為.LIB)。在使用靜態庫的情況下,在編譯鏈接可執行文件時,鏈接器從庫中復制這些函數和數據並把它們和應用程序的其它模塊組合起來創建最終的可執行文件(.EXE文件)。

 

在使用動態庫的時候,往往提供兩個文件:一個引入庫一個DLL。引入庫包含被DLL導出的函數和變量的符號名,DLL包含實際的函數和數據。在編譯鏈接可執行文件時,只需要鏈接引入庫,DLL中的函數代碼和數據並不復制到可執行文件中,在運行的時候,再去加載DLL,訪問DLL中導出的函數。

 

使用動態鏈接庫的好處

可以采用多種編程語言來編寫。

增強產品的功能。

提供二次開發的平台。

簡化項目管理。

可以節省磁盤空間和內存。

有助於資源的共享。

有助於實現應用程序的本地化。

 

 

動態鏈接庫加載的兩種方式

隱式鏈接

顯示加載

 

 vs2012

第一步

第二步

第三步

 

在空白的文件中寫入下列代碼

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


int subtract(int a, int b)
{
    return a - b;
}

然后編譯在Dll1目錄下的debug文件夾下會生成Dll1.dll文件

有了Dll1.dll文件,其他的.cpp文件還不能去訪問動態鏈接庫里面的函數,如果其他的程序想要使用動態鏈接庫里的函數,那么這些函數必須是導出的函數。

查看動態鏈接庫中哪些函數是被導出的 的方法

 

D:\vs2012\VC\bin 這個路徑是你安裝vs2012的路徑 這個路徑下有一個dumbin.exe文件

首先將D:\vs2012\VC\bin下的vcvars32.bat文件拖拽到 命令提示符里面

然后按照下面的方法輸入 輸入的目錄是你Dll1.dll文件所在的目錄

接着按照下面的輸入紅框中的內容

藍框中顯示沒有導出函數

 

修改代碼按照下面

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


_declspec(dllexport) int subtract(int a, int b)
{
	return a - b;
}

_declspec是關鍵字,作用將函數變為導出函數。

再次使用dumpbin,我們會看到導出函數,顯示在藍框中

下面去編寫測試程序來調用動態鏈接庫

第一步

創建MFC程序,命名為DllTest

選擇基於對話框的程序

 

創建兩個按鈕

Add id IDC_BTN_ADD

Subtract id IDC_BTN_SUBTRACT

雙擊兩個控件會產生兩個消息響應函數

 

extern int add(int a, int b);
extern int subtract(int a, int b);
void CDllTestDlg::OnBnClickedBtnAdd()
{
// TODO: 在此添加控件通知處理程序代碼
}


void CDllTestDlg::OnBnClickedBtnSubtract()
{
// TODO: 在此添加控件通知處理程序代碼
}

在這兩個函數中我們分別調用動態鏈接庫中的add函數和subtract函數

在調用之前我們要聲明一下,表明這兩個函數是在外部定義的函數

完整代碼

extern int add(int a, int b);
extern int subtract(int a, int b);
void CDllTestDlg::OnBnClickedBtnAdd()
{
	// TODO: 在此添加控件通知處理程序代碼
	CString str;
	str.Format(_T("5+3=%d"), add(5, 3));
	MessageBox(str);
}


void CDllTestDlg::OnBnClickedBtnSubtract()
{
	// TODO: 在此添加控件通知處理程序代碼
	CString str;
	str.Format(_T("5-3=%d"), subtract(5, 3));
	MessageBox(str);

}

  

編譯會出現下面的錯誤

1>DllTestDlg.obj : error LNK2019: 無法解析的外部符號 "int __cdecl add(int,int)" (?add@@YAHHH@Z),該符號在函數 "public: void __thiscall CDllTestDlg::OnBnClickedBtnAdd(void)" (?OnBnClickedBtnAdd@CDllTestDlg@@QAEXXZ) 中被引用
1>DllTestDlg.obj : error LNK2019: 無法解析的外部符號 "int __cdecl subtract(int,int)" (?subtract@@YAHHH@Z),該符號在函數 "public: void __thiscall CDllTestDlg::OnBnClickedBtnSubtract(void)" (?OnBnClickedBtnSubtract@CDllTestDlg@@QAEXXZ) 中被引用

解決方法

K:\c++\Dll1\Debug是之前生成Dll1.lib的路徑

然后再編譯會出現下面的問題

解決辦法

將之前生成的Dll1.dll文件拷貝到當前工程的Debug目錄下

重新編譯執行

以上內容參考孫鑫老師的MFC視頻


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM