模塊定義文件

模塊定義文件

模塊定義 (.def) 文件為鏈接器提供有關被鏈接程序的導出、屬性及其他方面的信息。生成 DLL 時,.def 文件最有用。由於存在可代替模塊定義語句使用的鏈接器選項,通常不需要 .def 文件。也可以將 __declspec(dllexport) 用作指定導出函數的手段。在鏈接器階段可以使用 /DEF(指定模塊定義文件)鏈接器選項調用 .def 文件。如果生成的 .exe 文件沒有導出,使用 .def 文件將使輸出文件較大並降低載入速度。

通俗解釋


在VC++中,生成DLL可以不使用.def文件。只需要在VC++的函數定義前要加__declspec(dllexport)修飾就可以了。但是使用__declspec(dllexport)和使用.def文件是有區別的。如果DLL是提供給VC++用戶使用的,你只需要把編譯DLL時產生的.lib提供給用戶,它可以很輕鬆地調用你的DLL。但是如果你的DLL是供其他程序如VBdelphi,以及.NET用戶使用的,那麼會產生一個小麻煩。因為VC++對於__declspec(dllexport)聲明的函數會對函數名尾附加函數在DLL中的地址,如下面的函數:
__declspec(dllexport) int __stdcallIsWinNT()
會轉換為IsWinNT@0,這樣你在VB中必須這樣聲明:
Declare Function IsWinNT Lib "my.dll" Alias "IsWinNT@0" () As Long
@的後面的數由於參數類型不同而可能不同。這顯然不太方便。所以如果要想避免這種轉換,就要使用.def文件方式。
EXPORTS後面的數可以不給,系統會自動分配一個數。對於VB、PBDelphi用戶,通常使用按名稱進行調用的方式,這個數關係不大,但是對於使用.lib鏈接的VC程序來說,不是按名稱進行調用,而是按照這個數進行調用的,所以最好給出。
除了.def的解決方案外,還可以原樣編譯:

定義格式


.def 文件中的第一條 LIBRARY 語句不是必須的,但LIBRARY 語句後面的 DLL 的名稱必須正確,即與生成的動態鏈接庫的名稱必須匹配。此語句將 .def 文件標識為屬於 DLL。鏈接器將此名稱放到 DLL 的導入庫中。
EXPORTS 語句列出名稱,可能的話還會列出 DLL 導出函數的序號值。通過在函數名的後面加上 @ 符和一個數字,給函數分配序號值。當指定序號值時,序號值的範圍必須是從 1 到 N,其中 N 是 DLL 導出函數的個數。
LIBRARY BTREE
EXPORTS
Insert @1
Delete @2
Member @3
Min @4
如果使用 MFC DLL 嚮導創建 MFC DLL,則嚮導將為您創建主幹 .def 文件並將其自動添加到項目中。添加要導出到此文件的函數名。對於非 MFC DLL,必須親自創建 .def 文件並將其添加到項目中。
如果導出 C++ 文件中的函數,必須將修飾名放到 .def 文件中,或者通過使用外部“C”定義具有標準 C 鏈接的導出函數。如果需要將修飾名放到 .def 文件中,則可以通過使用 DUMPBIN 工具或 /MAP 鏈接器選項來獲取修飾名。請注意,編譯器產生的修飾名是編譯器特定的。如果將 Visual C++ 編譯器產生的修飾名放到 .def 文件中,則鏈接到 DLL 的應用程序必須也是用相同版本的 Visual C++ 生成的,這樣調用應用程序中的修飾名才能與 DLL 的 .def 文件中的導出名相匹配。