動態鏈結庫小結

2021-06-07 09:15:09 字數 4172 閱讀 3941

***.lib //靜態庫

***x.dll ***x.lib //分別是動態庫動態庫的引入庫

1: 拷入動態庫dll 引入庫lib;

2: 加入標頭檔案

3: alt+f7 link選項卡 object/library modules:中輸入引入庫如***.lib

第3步也可以用這句**代替:#pragma comment(lib,"mydll.lib")

如extern "c"_declspec(dllimport) int add(int a,int b);)可寫成:

#define dll_api_win32test extern "c"

_declspec(dllimport)//匯入

dll1_api int add(int a,int b);

如果同時隱式載入許多dll,會造成程式啟動慢,而且有些函式根本就不需要呼叫的,所以可以選擇只有需要呼叫函式時才載入函式進行呼叫,這時候就會到下面的顯示鏈結了,隱式載入其實也是呼叫函式

loadlibrary乙個乙個載入的.

要使用函式loadlibrary

1:c++和c呼叫約定

hinstance hinst;

hinst=loadlibrary("dlltest.dll");

typedef int (*addproc)(int a,int b);

addproc add=(addproc)getprocaddress(hinst,add);//add是dlltest.dll中匯出的函式名

if(!add)

freelibrary(hinst);//呼叫完,解除安裝dll

2:c++和標準呼叫約定

hinstance hinst;

hinst=loadlibrary("dlltest.dll");

typedef int (_stdcall *addproc)(int a,int b);//如果dll是paska呼叫約定也就是標準呼叫約定

addproc add=(addproc)getprocaddress(hinst,add);//add是dlltest.dll中匯出的函式名

if(!add)

freelibrary(hinst);//呼叫完,解除安裝dll

3:c++和c++呼叫約定,編寫dll時沒有加extern "c",查得dll匯出函式為 ?add@yahhh@z

並且為第1個函式

hinstance hinst;

hinst=loadlibrary("dlltest.dll");

typedef int (*addproc)(int a,int b);//如果dll是paska呼叫約定也就是標準呼叫約定

addproc add=(addproc)getprocaddress(hinst,"?add@yahhh@z");//add是dlltest.dll中匯出的函式名

//addproc add=(addproc)getprocaddress(hinst,makeintresource(1));//或者這樣寫,指的是第1個函式add

if(!add)

freelibrary(hinst);//呼叫完,解除安裝dll

假設c盤有檔案:***.exe ***x.dll

在cmd下輸入:

進入c盤.

執行命令: dumpin -imports ***.exe 以檢視匯入***.exe 的函式

執行命令: dumpin -exports ***x.dll 以查***x.dll 匯出了哪些函式

c++編譯器在匯出函式的時候,會做名字改編(比如:?函式名@@yahhh@z),把函式名字改編後,c編譯器編寫的呼叫端程式,無法識別函式,所以需要加關鍵字 extern "c" 至使c++編譯器沒有發生名字改編(比如:函式名),以確保c呼叫端正確識別以呼叫。extern "c" 中的字母c要大寫;這就是c++和c的呼叫約定了.

但是如果在函式名前面有加關鍵字 _stdcall 就成c++和標準呼叫語言 之間呼叫約定了.比如 得爾非語言..

例一 a:匯出全域性函式:c++與c 呼叫約定,

在檢視dll 直接匯出的 函式名

//標頭檔案 dll***.h//是給呼叫者用的 比如: #include "dll***.h"

//dll_api_win32test 在呼叫者不要再定義

#ifdef dll_api_win32test

#else

#define dll_api_win32test extern "c"

_declspec(dllimport)//匯入

#endif

dll_api_win32test int add(int a,int b);//未寫成_stdcall add(int a,int b);

dll_api_win32test int _stdcall subtract(int a,int b);//未寫成_stdcall subtract(int a,int b);

//原始檔

#define dll_api_win32test extern "c"

_declspec(dllexport)

//匯出

#include "dll***.h"

int add(int a,int b

int subtract(int a,int b)

例一 b:匯出全域性函式:c++和標準呼叫語言 呼叫約定,

在檢視dll 直接匯出的 _+函式名+引數所佔位元組數

//標頭檔案 dll***.h//是給呼叫者用的 比如: #include "dll***.h"

//所以dll_api_win32test 在呼叫者不要再定義

#ifdef dll_api_win32test

#else

#define dll_api_win32test extern "c"

_declspec(dllimport)//匯入

#endif

dll_api_win32test int _stdcall add(int a,int b);

dll_api_win32test int _stdcall subtract(int a,int b);

//原始檔

#define dll_api_win32test extern "c"

_declspec(dllexport)

//匯出

#include "dll***.h"

int _stdcall add(int a,int b)//_stdcall表示的是標準呼叫約定,表示winapi,paska呼叫約定

int _stdcall subtract(int a,int b))//_stdcall表示的是標準呼叫約定,表示winapi,paska呼叫約定

例二 匯出整個類:

//標頭檔案 dll***.h

#ifdef dll_api_win32test

#else

#define dll_api_win32test extern "c"

_declspec(dllimport)//匯入

#endif

class dll_api_win32test point//匯出整個類,類保持類的本性 如:private:還是一樣,是私有的;

//原始檔

#define dll_api_win32test extern "c"

_declspec(dllexport)

//匯出

#include "dll***.h"

#include

using namespace std;

void point::output(int x,int y);

//原始檔

#define dll_api_win32test extern "c"

_declspec(dllexport)

//匯出

#include "dll***.h"

#include

using namespace std;

void point::output(int x,int y)

int subtract(int a,int b)

呼叫方法就是上面所使用的動態載入方法:

void cdllusedemodlg::onbtnusefun()

cstring str;

str.format("5+3=%d",add(5,3));

messagebox(str);

}

動態鏈結庫小結

鏈結庫概述 使用動態鏈結庫可以實現軟體設計的模組化,動態鏈結庫是在執行時才進行連線並能夠共享的函式庫,可以將不同功能的模組封裝到不同的鏈結庫中,功能相同或相似的模組封裝到相同的鏈結庫中。鏈結庫是乙個以二進位制方式儲存資料的磁碟檔案,它本身不能執行,需要其他的應用程式執行時載入或編譯前進行引用。dll...

動態鏈結庫 靜態鏈結庫

包含標頭檔案和庫 idir 指定編譯查詢標頭檔案的目錄,常用於查詢第三方的庫的標頭檔案,例 gcc test.c i.inc o test。ldir 指定鏈結時查詢lib的目錄,常用於查詢第三方庫。llibrary 指定額外鏈結的lib庫 巨集定義 dmacro 以字串 1 預設值 定義 macro...

靜態鏈結庫 動態鏈結庫

庫是寫好的現有的,成熟的,可以復用的 現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的 都從零開始,因此庫的存在意義非同尋常。本質上來說庫是一種可執行 的二進位制形式,可以被作業系統載入記憶體執行。庫有兩種 靜態庫 a lib 和動態庫 so dll windows上對應的是.lib dll ...