關於dll的函式:
用於宣告匯入匯出函式
__declspec(dllexport) 宣告乙個匯出函式,一般用於dll中
__declspec(dllimport) 宣告乙個匯入函式,一般用於使用某個dll的exe中
更詳細的可以看msdn
動態鏈結庫中定義有兩種函式:匯出函式(export function)和內部函式(internal function)。
匯出函式可以被其它模組呼叫,內部函式在定義它們的dll程式內部使用。
輸出函式的方法有以下幾種:
1、傳統的方法
在模組定義檔案的export部分指定要輸入的函式或者變數。語法格式如下:
entryname[=internalname] [@ordinal[noname]] [data] [private]
其中:
entryname是輸出的函式或者資料被引用的名稱;
internalname同entryname;
@ordinal表示在輸出表中的順序號(index);
noname僅僅在按順序號輸出時被使用(不使用entryname);
data表示輸出的是資料項,使用dll輸出資料的程式必須宣告該資料項為_declspec(dllimport)。
上述各項中,只有entryname項是必須的,其他可以省略。
對於「c」函式來說,entryname可以等同於函式名;但是對「c++」函式(成員函式、非成員函式)
來說,entryname是修飾名。可以從.map映像檔案中得到要輸出函式的修飾名,或者使用
dumpbin /symbols得到,然後把它們寫在.def檔案的輸出模組。dumpbin是vc提供的乙個工具。
如果要輸出乙個「c++」類,則把要輸出的資料和成員的修飾名都寫入.def模組定義檔案。
2、在命令列輸出
對鏈結程式link指定/export命令列引數,輸出有關函式。
3、使用mfc提供的修飾符號_declspec(dllexport)
在要輸出的函式、類、資料的宣告前加上_declspec(dllexport)的修飾符,表示輸出。__declspec
(dllexport)在c呼叫約定、c編譯情況下可以去掉輸出函式名的下劃線字首。extern "c "使得在c++中
指明該函式使用c編譯方式。輸出的「c」函式可以從「c」**裡呼叫。
例如,在乙個c++檔案中,有如下函式:
extern "c "
其輸出函式名為:test
mfc提供了一些巨集,就有這樣的作用。
afx_class_import:__declspec(dllexport)
afx_api_import:__declspec(dllexport)
afx_data_import:__declspec(dllexport)
afx_class_export:__declspec(dllexport)
afx_api_export:__declspec(dllexport)
afx_data_export:__declspec(dllexport)
afx_ext_class: #ifdef _afxext
afx_class_export
#else
afx_class_import
afx_ext_api:#ifdef _afxext
afx_api_export
#else
afx_api_import
afx_ext_data:#ifdef _afxext
afx_data_export
#else
afx_data_import
像afx_ext_class這樣的巨集,如果用於dll應用程式的實現中,則表示輸出(因為_afx_ext被定義,通
常是在編譯器的標識引數中指定該選項/d_afx_ext);如果用於使用dll的應用程式中,則表示輸入
(_afx_ext沒有定義)。
要輸出整個的類,對類使用_declspec(_dllexpot);要輸出類的成員函式,則對該函式使用
_declspec(_dllexport)。如:
class afx_ext_class ctextdoc : public cdocument
extern "c " afx_ext_api void winapi initmydll();
這幾種方法中,最好採用第三種,方便好用;其次是第一種,如果按順序號輸出,呼叫效率會高些;
最次是第二種。
六、模組定義檔案(.def)
模組定義檔案(.def)是乙個或多個用於描述dll屬性的模組語句組成的文字檔案,每個def檔案至少必
須包含以下模組定義語句:
* 第乙個語句必須是library語句,指出dll的名字;
* exports語句列出被匯出函式的名字;將要輸出的函式修飾名羅列在exports之下,這個名字必須與
定義函式的名字完全一致,如此就得到乙個沒有任何修飾的函式名了。
* 可以使用description語句描述dll的用途(此句可選);
* "; "對一行進行注釋(可選)。
七、dll程式和呼叫其輸出函式的程式的關係
1、dll與程序、執行緒之間的關係
dll模組被對映到呼叫它的程序的虛擬位址空間。
dll使用的記憶體從呼叫程序的虛擬位址空間分配,只能被該程序的執行緒所訪問。
dll的控制代碼可以被呼叫程序使用;呼叫程序的控制代碼可以被dll使用。
dll使用呼叫程序的棧。
2、關於共享資料段
dll定義的全域性變數可以被呼叫程序訪問;dll可以訪問呼叫程序的全域性資料。使用同一dll的每乙個
程序都有自己的dll全域性變數例項。如果多個執行緒併發訪問同一變數,則需要使用同步機制;對乙個
dll的變數,如果希望每個使用dll的執行緒都有自己的值,則應該使用執行緒區域性儲存(tls,thread
local strorage)。
在程式裡加入預編譯指令,或在開發環境的專案設定裡也可以達到設定資料段屬性的目的.必須給
這些變數賦初值,否則編譯器會把沒有賦初始值的變數放在乙個叫未被初始化的資料段中。
作者為:rivershan
關於Dll 匯出函式名 ZZ
使用dependency看dll的匯出函式的名字,會發現有一些有意思的東西,這大多是和編譯dll時候指定dll匯出函式的匯出符有關係。當你使用extern c 的情況下 stdcall會使匯出函式名字前面加乙個下劃線,後面加乙個 再加上引數的位元組數,比如 fun 4就是4個位元組 fastcall...
關於生成DLL
現在寫的通用的平台,client server side 都要求外掛程式形式,每乙個外掛程式宿主於乙個動態庫中,在symbian中,動態的呼叫有些不是很方便,現在總結一下其各種型別庫的載入形式。0,靜態庫 1,動態庫 a,靜態載入 b,動態載入 動態庫動態載入的幾個問題 1,在emulator上不能...
關於資源DLL的開發
上面兩篇文章很不錯,分別是講 cwnd getdlgitem和dll與exe模組切換的問題,mfc 模組中可能存在資源,在預設情況下,程序會在當前模組中查詢資源 dll或者exe 這樣就導致可能會找不到本來存在的資源 恰好在另乙個模組 對於cwnd getdlgitem,跟cwnd fromhand...