如何從dll文件導出對應的lib文件?
Visual C++ 開發工具提供了兩個命令行工具,一個是dumpbin.exe,另一個是lib.exe。利用這兩個工具即可從dll導出其對應的lib。
1、在命令行執行:
dumpbin /exports yourdll.dll > yourdll.def
2、編輯 yourdll.def 文件,使之格式與.def文件格式一致 。比如:
EXPORTS;
fn1;
fn2;
3、在命令行執行:
lib /def:yourdll.def /machine:i386 /out:yourdll.lib
//爲無LIB的DLL製作LIB函數符號輸入庫
本文介紹了在VC中針對無LIB時的DLL隱式鏈接,製作可供VC++使用的LIB函數符號輸入庫。具體步驟如下:
一、使用VC++的工具DUMPBIN將DLL中的導出函數表導出到一定義(.DEF)文件
EXAMPLE:
DUMPBIN VideoDeCoder.dll /EXPROTS /OUT:VideoDeCoder.def
二、將導出的.DEF文件整理爲一符合.DEF個數的函數導出文件
EXAMPLE:
VideoDeCoder.DEF 文件內容如下Dump of file VideoDeCoder.dll
File Type: DLL
Section contains the following exports for VideoDeCoder.dll
0 characteristics
3D49E48F time date stamp Fri Aug 02 09:46:55 2002
0.00 version
1 ordinal base
11 number of functions
11 number of names
ordinal hint RVA name
1 0 00010F60 _TM_ClearDecoderBuff@4
2 1 00010E80 _TM_CloseDecoder@4
3 2 00010F00 _TM_DecodePicture@4
4 3 00010ED0 _TM_DecodePictureHeader@4
5 4 00010FD0 _TM_GetFileEnd@4
6 5 00011030 _TM_GetUValue@4
7 6 00011060 _TM_GetVValue@4
8 7 00011000 _TM_GetYValue@4
9 8 00010E10 _TM_OpenDecoder@8
10 9 00010F30 _TM_ReturnType@4
11 A 00010F90 _TM_SetFileEnd@8
Summary
2000 .data
1000 .rdata
1000 .reloc
15000 .text
按照以下方法整理:
1)添加LIB說明 LIBRARY "VideoDeCoder" ;"xx"爲DLL名稱
DESCRIPTION "VideoDeCoder library"
2)去掉導出函數說明端以外的內容,在LIB說明下添加 "EXPROTS" 說明導出函數 LIBRARY "VideoDeCoder"
DESCRIPTION "VideoDeCoder library"
EXPORTS
ordinal hint RVA name
1 0 00010F60 _TM_ClearDecoderBuff@4
2 1 00010E80 _TM_CloseDecoder@4
3 2 00010F00 _TM_DecodePicture@
4 3 00010ED0 _TM_DecodePictureH
5 4 00010FD0 _TM_GetFileEnd@4
6 5 00011030 _TM_GetUValue@4
7 6 00011060 _TM_GetVValue@4
8 7 00011000 _TM_GetYValue@4
9 8 00010E10 _TM_OpenDecoder@8
10 9 00010F30 _TM_ReturnType@4
11 A 00010F90 _TM_SetFileEnd@8
3)將所有的函數放至行首,去掉 "hint" 和 "RVA" 數據,留下函數的序號 "ordinal" ,在序號前加上 "@" 符號 形成 "_導出函數名@參數字節和 @序號" 此種格式(__stdcall 方式調用導出的函數符號是 "函數名稱@參數字節和"). 最後形成.DEF文件如下:
LIBRARY "VideoDeCoder"
DESCRIPTION "VideoDeCoder library"
EXPORTS
TM_ClearDecoderBuff@4 @1
TM_CloseDecoder@4 @2
TM_DecodePicture@4 @3
TM_DecodePictureHeader@4 @4
TM_GetFileEnd@4 @5
TM_GetUValue@4 @6
TM_GetVValue@4 @7
TM_GetYValue@4 @8
TM_OpenDecoder@8 @9
TM_ReturnType@4 @10
TM_SetFileEnd@8 @11
三、使用VC++的LIB工具,帶/DEF:(.def文件名) /MACHINE:IX86(80X86機器),就輸出符合VC++格式的的LIB文件了.
EXAMPLE:LIB /DEF:VideoDeCoder.def /MACHINE:IX86
四、接時帶上LIB文件鏈接;注意的是當有些動態庫DUMPBIN的只有函數名,無"@nn"的參數格式,如C++Builder寫的DLL,輸出就只有 函數名符號,鏈接時就會報錯: error LNK2002:unresolved external symbol "functionname@nn" 提示程序中引入的函數符號無法識別,這時只要將DEF文件中相應的函數名稱改爲functionname@nn方式,重新建立LIB,重新鏈接即可.
def文件格式
以下摘自MSDN,希望有幫助。不過在VC下編程好像用不着自己定義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) 時有效。
轉載自:http://www.cnblogs.com/dongzhiquan/archive/2009/08/04/1994764.html