.def文件格式

模塊定義(.def)文件 


模塊定義(.def)文件爲鏈接器提供有關被鏈接程序的導出、屬性及其他方面的信息.生成 DLL 時,.def 文件最有用.由於存在可代替模塊定義語句使用的鏈接器選項,通常不需要.def文件.也可以將__declspec(dllexport)用作指定導出函數的手段. 


在鏈接器階段可以使用 /DEF(指定模塊定義文件)鏈接器選項調用.def文件. 


如果生成的 .exe 文件沒有導出,使用.def文件將使輸出文件較大並降低加載速度. 


模塊定義語句的規則 


下列語法規則適用於.def文件中的所有語句.其他適用於特定語句的規則與各語句一起加以說明. 


語句、屬性關鍵字和用戶指定的標識符區分大小寫. 

包含空格或分號(;)的長文件名必須用引號(")引起. 

使用一個或多個空格、製表符或換行符,將語句關鍵字同其參數分開和將各語句分開.指定參數的冒號(:)或等號(=)兩旁有零個或多個空格、製表符或換行符. 

如果使用 NAME 或 LIBRARY 語句,則這些語句必須位於所有其他語句之前. 

在.def文件中,SECTIONS 和 EXPORTS 語句可以出現多次.每個語句都可以採用多個規範,各規範間必須用一個或多個空格、製表符或換行符分開.語句關鍵字必須在第一個規範的前面出現一次,並且可以在每個附加規範的前面重複. 

許多語句都具有等效的 LINK 命令行選項.有關其他詳細信息,請參閱相應的 LINK 選項說明. 

.def 文件中的註釋由每個註釋行開始處的分號(;)指定.註釋不能與語句共享一行,但可以在多行語句的規範間出現.(SECTIONS 和 EXPORTS 爲多行語句.) 

以十進制或十六進制爲基礎指定數值參數. 

如果字符串參數與保留字匹配,則必須用雙引號(")將字符串參數引起. 


DESCRIPTION "text" 


該語句將字符串寫入 .rdata 節.將指定的 text 用單引號或雙引號(' 或 ")引起.若要在字符串中使用引號(單引號或雙引號),請用其他類型的標記括住字符串. 


在模塊定義文件中,DESCRIPTION 僅在生成虛擬設備驅動程序(VxD)時有效. 


EXETYPE:dynamic | dev386 


在模塊定義文件中,EXETYPE 僅在生成虛擬設備驅動程序(VxD)時有效.如果生成虛擬設備驅動程序時在模塊定義文件中沒有指定 EXETYPE,並且如果沒有指定 /EXETYPE 鏈接器選項,則靜態加載(dev386)生效. 


EXPORTS 

definitions 


EXPORTS 語句引入了一個由一個或多個 definitions(導出的函數或數據)組成的節.每個定義必須在單獨一行上.EXPORTS 關鍵字可以在第一個定義所在的同一行上或在前一行上..def 文件可以包含一個或多個 EXPORTS 語句. 


導出 definitions 的語法爲: 


entryname[=internalname] [@ordinal [NONAME]] [PRIVATE] [DATA] 

entryname 是要導出的函數名或變量名.這是必選項.如果導出的名稱與 DLL 中的名稱不同,則通過 internalname 指定 DLL 中導出的名稱.例如,如果 DLL 導出函數 func1(),要將它用作 func2(),則應指定: 


EXPORTS 

func2=func1 

@ordinal 允許指定是序號而不是函數名將進入 DLL 的導出表.這有助於最小化 DLL 的大小..LIB 文件將包含序號與函數之間的映射,這使您得以像通常在使用 DLL 的項目中那樣使用函數名. 


可選的 NONAME 關鍵字允許只按序號導出,並減小結果 DLL 中導出表的大小.但是,如果要在 DLL 上使用 GetProcAddress,則必須知道序號,因爲名稱將無效. 


可選的 PRIVATE 關鍵字禁止將 entryname 放到由 LINK 生成的導入庫中.它對同樣是由 LINK 生成的圖像中的導出無效. 


可選的 DATA 關鍵字指定導出的是數據,而不是代碼.例如,可以導出數據變量,如下所示: 


EXPORTS 

i DATA 

當對同一導出使用 PRIVATE 和 DATA 時,PRIVATE 必須位於 DATA 的前面. 


有三種導出定義的方法,按照建議的使用順序依次爲: 


源代碼中的 __declspec(dllexport)關鍵字 

.def 文件中的 EXPORTS 語句 

LINK 命令中的 /EXPORT 規範 

所有這三種方法可以用在同一個程序中.LINK 在生成包含導出的程序時還創建導入庫,除非生成中使用了 .exp 文件. 


以下是 EXPORTS 節的示例: 


EXPORTS 

DllCanUnloadNow @1 PRIVATE DATA 

DllWindowName = Name DATA 

DllGetClassObject @4 NONAME PRIVATE 

DllRegisterServer @7 

DllUnregisterServer 

注意,使用.def文件從 DLL 中導出變量時,不需要在變量上指定 __declspec(dllexport).但是,在任何使用 DLL 的文件中,仍必須在數據聲明上使用 __declspec(dllimport). 


LIBRARY [library][BASE=address] 


該語句通知 LINK 創建 DLL.LINK 同時還創建導入庫,除非生成中使用了 .exp 文件. 


library 參數指定 DLL 的名稱.也可以使用 /out 鏈接器選項指定 DLL 輸出名. 


BASE=address 參數設置操作系統用來加載 DLL 的基址.該參數重寫 0x10000000 的默認 DLL 位置.有關基址的詳細信息,請參閱 /BASE 選項說明. 


請記住,在生成 DLL 時使用 /DLL 鏈接器選項. 


/HEAP:reserve[,commit] 


HEAPSIZE 所展示的功能與 /HEAP 鏈接器選項相同. 


NAME [application][BASE=address] 


該語句指定主輸出文件的名稱.另一種指定輸出文件名的方法是使用 /out 鏈接器選項,而另一種設置基址的方法是使用 /BASE 鏈接器選項.如果兩種方法都指定了,則 /OUT 重寫 NAME. 


如果生成 DLL,NAME 將隻影響 DLL 名. 


SECTIONS 

definitions 


SECTIONS 語句引入了一個由一個或多個 definitions(關於項目輸出文件各節的訪問說明符)組成的節.每個定義必須在單獨一行上.SECTIONS 關鍵字可以在第一個定義所在的同一行或前一行上..def 文件可以包含一個或多個 SECTIONS 語句. 


該 SECTIONS 語句爲圖像文件中的一節或多節設置屬性,並可用於重寫每種節類型的默認屬性. 


definitions 的格式爲: 


.section_name specifier 


此處,.section_name 爲程序圖像中的節名,specifier 爲下列一個或多個訪問修飾符: 


EXECUTE 

READ 

SHARED 

WRITE 

用空格分開修飾符名.例如: 


SECTIONS 

.rdata READ WRITE 

SECTIONS 標記 definitions 節列表的開始位置.每個定義必須在單獨一行上.SECTIONS 關鍵字可以在第一個定義所在的同一行或前一行上. .def 文件可以包含一個或多個 SECTIONS 語句.支持 SEGMENTS 關鍵字作爲 SECTIONS 的同義詞. 


Visual C++ 的早期版本支持: 


section [CLASS 'classname'] specifier 

出於兼容性考慮,支持 CLASS 關鍵字,但忽略了它. 


另一種指定節屬性的方法是使用 /SECTION 選項. 


STACKSIZE reserve[,commit] 


該語句設置堆棧的大小(以字節爲單位).另一種設置堆棧的方法是使用堆棧分配(/STACK)選項.有關 reserve 和 commit 參數的詳細信息,請參閱關於該選項的文檔. 


該選項對 DLL 無效. 


STUB:filename 


當用於生成虛擬設備驅動程序(VxD)的模塊定義文件時,STUB 允許指定包含將在 VxD 中使用的 IMAGE_DOS_HEADER 結構(在 WINNT.H 中定義)而不是默認頭的文件名. 


另一種指定 filename 的方法是使用 /STUB 鏈接器選項. 


在模塊定義文件中,STUB 僅在生成虛擬設備驅動程序(VxD)時有效. 


VERSION major[.minor] 


該語句通知 LINK 將一個數字放到 .exe 文件或 DLL 的頭中.major 和 minor 參數是從 0 到 65,535 的範圍內的十進制數.默認值爲 0.0 版. 


另一種指定版本號的方法是使用版本信息(/VERSION)選項. 


VXD filename 


允許指定虛擬設備驅動程序(VxD)的名稱.默認情況下,VxD 獲取與第一個對象文件相同的名稱. 


另一種指定虛擬設備驅動程序版本的方法是使用 /VXD 鏈接器選項,另一種命名輸出文件的方法是使用 /out 選項. 


在模塊定義文件中,VXD 僅在生成虛擬設備驅動程序(VxD)時有效.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章