|
|
请大家注意!这种方法只能应用于输出为C格式的__stdcall调用方式!
* T7 L0 A' q/ G. H* w# l
+ C/ w+ U# S5 V I1. 使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件3 D7 E4 ?& r$ L
EXAMPLE:
1 R8 ^" d, Y l2 M C4 U* L DUMPBIN VideoDeCoder.dll /EXPROTS /OUT:VideoDeCoder.def/ ~) O$ c9 V3 @
/ \1 q# B( [- x7 y; E2. 将导出的.DEF文件整理为一符合.DEF个数的函数导出文件1 ^2 J+ y4 D$ J6 V
EXAMPLE:
& o% d; k/ X, T( l+ {7 V VideoDeCoder.DEF 文件内容如下
* D& e9 c5 p5 B) y3 T/ r- n
4 j5 J9 M& \/ l5 T; E Dump of file VideoDeCoder.dll 1 b1 @; p* U( w$ q1 _- z8 Q
3 ~, T1 R9 f: e4 K
File Type: DLL ! x4 V/ ?1 C7 `# `: @9 E& J
; _0 ?. ]. I' a: h l2 H Section contains the following exports for VideoDeCoder.dll
$ [8 W, P/ ]7 H1 v6 L: x7 x
6 N0 \/ j4 k) g' } x) d ]' o 0 characteristics
! V' ]' ]( W; }* D1 ]3 U 3D49E48F time date stamp Fri Aug 02 09:46:55 2002
# Q e9 B; o2 r: i0 @ 0.00 version 1 l+ H5 g+ L; g' Z1 k( I
1 ordinal base
- |8 R# r) `! |2 O 11 number of functions
# t2 }, c0 F" w( f. j+ ^+ ` 11 number of names
/ i5 b6 I8 B. `; h9 D8 J% b
m: Q+ ^9 ~3 D/ c ordinal hint RVA name
; X' J1 V2 u9 E8 t 8 e Y# Y4 a f( Q0 W
1 0 00010F60 _TM_ClearDecoderBuff@4
0 d3 c! T; b) p 2 1 00010E80 _TM_CloseDecoder@4 4 }, w/ U. o: \* t* j
3 2 00010F00 _TM_DecodePicture@4
% e( S3 \. R3 n9 v$ k S/ X/ t 4 3 00010ED0 _TM_DecodePictureHeader@4
# W3 j0 c5 K- j 5 4 00010FD0 _TM_GetFileEnd@4
) {: K9 {9 y4 L4 E7 Z. i$ T 6 5 00011030 _TM_GetUValue@4
4 l3 e9 x1 m# W6 P4 l 7 6 00011060 _TM_GetVValue@4
" a1 d+ \9 q7 b. X 8 7 00011000 _TM_GetYValue@4
+ r5 C3 }2 z2 }3 x$ e 9 8 00010E10 _TM_OpenDecoder@8
R6 [7 \* B; O: q7 F5 e7 R6 \' _ 10 9 00010F30 _TM_ReturnType@4 9 `9 [! J% v% T: s' O9 {
11 A 00010F90 _TM_SetFileEnd@8
; L7 i8 r+ w& d1 U) I8 [# m, ^ M ) t# J8 X b) j) q7 ]: e6 @# ]
Summary
2 K, X3 Z k! N3 p & t3 L3 @# d% [- ^
2000 .data % _9 ?, k* Q$ J4 N" U
1000 .rdata
- H9 S# R; s4 o1 p 1000 .reloc : Y' Y$ H" X, w: |" V
15000 .text
, Z5 i- D; F1 `$ d2 b1 F ~ 按照以下方法整理:
. `' k" b6 F: h1 u0 p 1>添加LIB说明
; I5 |1 w6 }( x# ?3 c5 O+ o( C LIBRARY "VideoDeCoder" ;"xx"为DLL名称# L) Z+ p* W& l% K. H( H* C
DESCRIPTION "VideoDeCoder library" $ y6 \ s( G9 ^
2>去掉导出函数说明端以外的内容,在LIB说明下添加 "EXPROTS" 说明导出函数
2 W3 V8 e2 ]% I3 Q7 R3 O LIBRARY "VideoDeCoder" V) Z; k/ F2 t+ g
DESCRIPTION "VideoDeCoder library"
# G2 Y) G* ]: O EXPORTS* m0 F1 G+ Q8 G: [5 G
ordinal hint RVA name $ a, U9 s4 a6 S/ ^$ j0 Q
; [* M7 k4 d: a# Z 1 0 00010F60 _TM_ClearDecoderBuff@4 / X' w- a4 j# ~7 V, \
2 1 00010E80 _TM_CloseDecoder@4 , r( S0 c- ?) n
3 2 00010F00 _TM_DecodePicture@
& w, E! |$ W/ l- _$ e# O) I 4 3 00010ED0 _TM_DecodePictureH 0 j8 f) T [3 {5 }% D3 `2 x
5 4 00010FD0 _TM_GetFileEnd@4 + w% J, }; o( {& |3 S7 c
6 5 00011030 _TM_GetUValue@4
' h) F& J0 A% w# T3 N8 g c: k 7 6 00011060 _TM_GetVValue@4
% A: \( Q$ _" k% V# L 8 7 00011000 _TM_GetYValue@4
* H; ?, c/ e) M4 L8 ^3 P 9 8 00010E10 _TM_OpenDecoder@8
" P( A& K# L* q/ J- F 10 9 00010F30 _TM_ReturnType@4 4 w7 Q* G. w: j4 n1 q7 [' s
11 A 00010F90 _TM_SetFileEnd@8 8 x' x- `( P1 @
3>将所有的函数放至行首,去掉 "hint" 和 "RVA" 数据,留下函数的序号 "ordinal" ,在序号前加上 "@" 符号+ R5 ~* Q+ T Z/ O9 v. S% c! W8 G
形成 "_导出函数名@参数字节和 @序号" 此种格式(__stdcall 方式调用导出的函数符号是 "函数名称@参数字节和").. z9 U; y7 t6 E# j- k/ \
最后形成.DEF文件如下:3 m& ]/ O( U* l$ F2 T# b
LIBRARY "VideoDeCoder" r7 X3 @( V8 O
DESCRIPTION "VideoDeCoder library"
9 j: e" |, d% V EXPORTS4 V* _1 B% c: z% L! o
3 ^& `- |7 O2 I3 ] X
TM_ClearDecoderBuff@4 @1 7 f" s4 J! Z" J# J T' q
TM_CloseDecoder@4 @2 % Z2 w3 ?2 q+ g5 m4 G/ p9 m
TM_DecodePicture@4 @3
5 _* B4 \4 I* C& [1 f TM_DecodePictureHeader@4 @4 i# p8 Z% f2 z+ D/ H
TM_GetFileEnd@4 @5
1 p' x& U0 J* J7 F v0 B: l TM_GetUValue@4 @6
% K- L# i/ ~, {, }5 l4 y# v- ~ TM_GetVValue@4 @7
' \6 u* v/ V1 X( \ TM_GetYValue@4 @8 f' I5 ~9 }" ^
TM_OpenDecoder@8 @9 ) B7 a ^$ D; r& r
TM_ReturnType@4 @10
: z, l7 \6 a; [- l4 }; r: j TM_SetFileEnd@8 @11
4 h6 s' e" l4 t7 J$ }) i3. 使用VC++的LIB工具,带/DEF:(.def文件名) /MACHINE:IX86(80X86机器),就输出符合VC++格式的的LIB文件了., P* |5 c; g0 Y6 X8 ]
EXAMPLE: O& ~2 S8 W; U5 ~0 \
LIB /DEF:VideoDeCoder.def /MACHINE:IX86 R( `, H4 Y7 V: ]4 q
4. 接时带上LIB文件链接;注意的是当有些动态库DUMPBIN的只有函数名,无"@nn"的参数格式,如C++Builder写的DLL,输出就只有函数名符号,链接时就会报错:% ?3 Z! h0 `! ? P7 ^ c8 \6 f
error LNK2002:unresolved external symbol "functionname@nn"
& O I; ^5 t8 L提示程序中引入的函数符号无法识别,这时只要将DEF文件中相应的函数名称改为functionname@nn方式,重新建立
. ]% }" X- P3 m3 [LIB,重新链接即可.
) `8 [& @* X" o$ R2 k. X' o. h+ @3 z( {* d+ s
这样就制作成功了符合VC调用方式的LIB了!: t) G) p( _' \: r- U/ U) o
参考:MSDN2000
8 o3 X0 Q7 Z) e3 @6 ?8 w: w要值得一说的是!BORLAND C++BUILDER有一个很好的工具IMPDEF可以直接将DLL中的函数输出到.DEF文件中,只要做一点点修改就可以成为符合VC的DEF文件!2 A( D6 e- Z6 _7 s
IMPDEF xxx.def xxx.dll
z0 G( L' D9 |% A) \: `2 ?) P' r这种方法只能应用于输出为C格式的__stdcall调用方式经过我的论证有些错误!我利用Borland C++和VC++做论证,发现:) c; Z; a9 F, b5 Q, P+ E
而在C++BUILDER中!
' u8 @7 g' y' M# O__cdecl的函数输出前会带一"_"& R# A" Y* K7 o- w6 f. m, |
__stdcall无特征,只输出函数名
4 h- p6 p- x/ y7 @! s& a__fastcall函数输出前带一"@"
# |3 Y) m/ ~$ s. Q都无"@nn"后缀格式!
' v! E/ O/ w# v! i在VC中!
: b# W3 m! E1 j2 g. }6 T__cdecl无特征,只输出函数名/ C# @/ X( D/ r7 U- I O5 r
__stdcall的函数输出前会带一"_"后缀带"@nn"
! i) E9 f4 C' ~" a: e: G2 v* ]__fastcall函数输出前带一"@"后缀带"@nn
9 {5 c @6 M' [1 T9 E! M只要将BC的DEF文件中函数申明格式转换为VC识别的格式就可以利用LIB工具生成LIB;要使用C分格输出(extern "C")才是必须的!而且别忘了在DEF文件中的函数申明不要带“_”啊!:)不然会出现error LNK2001的链接错误! |
|