***.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 ...