一、 編寫第乙個入門級dll檔案
1.新建乙個dlltest
的dll工程,加入一原始檔dlltest.cpp,包含add和subtract兩個函式如下:
_declspec(dllexport) int add(int a,int b)注意:在函式名前加上_declspec(dllexport)_declspec(dllexport) int subtract(int a,int b)
,這樣編譯後在連線的時候才會生成dlltest.lib(引入庫檔案)和dlltest.exp(輸出庫檔案),並且在命令提示符下用dumpbin命令可以看到匯出了哪些函式。
方法:在命令提示符下,轉到dll檔案所在目錄下,輸入dumpbin –exports dlltest.dll,列出匯出函式如下:
這裡注意到函式名字已經被改成了
?add@@yahhh@z
,這種現象叫做
名字粉碎
,是為了支援函式過載而做的。
2.編寫乙個基於對話方塊的mfc程式測試dll,工程名為calldll,放置兩個按紐add和subtract,響應按紐訊息,呼叫這個dll的add和subtract函式。
先新增響應按鈕訊息的函式onadd和onsubtract,然後在函式所在原始檔中寫完整函式體如下:
//extern int add(int,int);這裡採用隱式鏈結//extern int subtract(int,int);
_declspec(dllimport) int add(int,int);
_declspec(dllimport) int subtract(int,int);
void ccalldlldlg::onadd()
void ccalldlldlg::onsubtract()
注意:要用關鍵字extern先宣告這兩個函式,表明這兩個函式是在外部定義的(不過程式中將它注釋掉了)。最好是用_declspec(dllimport)表明函式是從動態鏈結庫的lib檔案中引入的,這樣效率更高。
將檔案dlltest.lib拷貝到此工程目錄下,並在project settings的link標籤下新增此檔案:(否則編譯會成功,但連線時會出錯提示找不到函式的定義)
編譯連線生成calldll.exe,這時用dumpbin -importscalldll.exe
檢視它的輸入資訊,可以看到它載入了dlltest.dll
。執行calldll.exe(要成功執行還需將dlltest.dll
拷貝到工程目錄或此exe所在目錄下)
這樣,最簡單的第乙個dll就完成了。
二、 編寫涉及到類和標頭檔案的dll檔案
1.新建乙個dlltest
的dll工程,加入一頭檔案dlltest.h和一原始檔dlltest.cpp。
dlltest.h:
#ifdef dll_apidlltest.cpp#else
#define dll_api _declspec(dllimport)
#endif
dll_api int add(int,int);
dll_api int subtract(int,int);
class dll_api point1 //將整個類匯出
;class point2
;
:
#define dll_api _declspec(dllexport)2.編寫乙個基於對話方塊的mfc程式測試dll,此時在工程中包含上面這個標頭檔案,不用在宣告匯入的類和函式了。#include "dlltest.h"
#include #include int add(int a,int b)
int subtract(int a,int b)
void point1::output(int x,int y)
void point1::output1(int x,int y)
void point2::output(int x,int y)
void point2::output1(int x,int y)
三、 使用模組定義檔案和動態載入動態鏈結庫
1.新建dlltest.dll工程,加入一原始檔dlltest.cpp,包含add和subtract兩個函式如下:
int add(int a,int b)2.使用模組定義檔案防止檔名改變,在目錄中新建dlltest.def檔案,增加到工程。int subtract(int a,int b)
library dlltest注:library和exports的用法參照msdn.exports
addsubtract
3.編譯後用dumpbin檢視到函式名沒有改變。
4.用動態載入的方法來呼叫dll檔案。
void ccalldlldlg::onadd()注意:1.cstring str;
str.format("2+3=%d",add(2,3));
messagebox(str);
freelibrary(hinst);
}
這裡呼叫的getprocaddress函式中的第二個引數是動態鏈結庫中匯出的函式名,如果動態鏈結庫中沒有用模組定義檔案防止函式名粉碎,則要用注釋掉的getprocaddress(hinst,"?add@@yahhh@z"),另外也可按序號訪問getprocaddress(hinst,makeintresource(1))。
2.使用模組定義檔案後,如果改變呼叫約定為_stdcall,函式名也不會被改變,但如果加上_stdcall定義函式,呼叫時也需要加上_stdcall,否則會出錯。
3.動態載入不需要將檔案dlltest.lib拷貝到此工程目錄下,並在project settings的link標籤下新增此檔案,只需將dll檔案拷貝到工程目錄下即可,並且通過dumpbin -imports calldll.exe檢視它的輸入資訊時,可以看到它並沒有載入dlltest.dll。
4.動態載入的好處是需要時再載入,可以提高執行的效率。當不使用dll時,呼叫freelibrary減少dll的使用計數,釋放dll資源,減少系統負擔。
5.不使用模組定義檔案,也可用extern "c"
使函式名保持不變,如#define dll1_api extern "c" _declspec(dllexport)
,但它只能匯出全域性函式,不能匯出類的成員函式,並且如果呼叫約定被改成了別的方式,此時函式名也被改變,所以一般不用這種方式。
Linux下C程式設計入門
這裡向大家介紹一下在linux unix 的機器上,進行 c c 程式設計的一些入門級知識。所需具備的背景知識 開發所需的基本環境 獲得幫助的途徑 通過乙個例項了解基本步驟 prerequisite 先決條件 在linux上編寫 c 程式,至少要熟悉以下兩方面的基礎知識 1 c語言的程式設計基礎,至...
C入門 C呼叫DLL
header.h ifndef header h define header h include include include dll 02.h int maxint int,int void t1 void testdll void t2 void testdll01 impl.cpp incl...
C 呼叫C 的DLL入門篇
首先,問什麼會出現c 程式呼叫c 編寫的dll檔案呢?下面簡單描述一下這種情況的背景。在新開發的專案中使用的新語言c 和新的技術方案webservice,但是在新專案中,一些舊的模組仍需要使用,一般採用c c 或delphi編寫,如何利用舊模組對與開發人員有三種方法可選擇 徹底改寫,你懂得,c 中的...