|
请大家注意!这种方法只能应用于输出为C格式的__stdcall调用方式!
M* r& y/ o- S( B
, ]1 a' _6 u5 ^$ K: S/ u( w) ^1. 使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件1 t: i; @. A0 e% V k
EXAMPLE:6 ^5 A" _: e: H9 r8 s- ]
DUMPBIN VideoDeCoder.dll /EXPROTS /OUT:VideoDeCoder.def- L. ~$ k) i3 @3 I; \8 x6 F
' b$ P5 Z9 r: |; }0 I2. 将导出的.DEF文件整理为一符合.DEF个数的函数导出文件3 J9 F: o# }; b/ ?- ^
EXAMPLE:7 Z; a& u( }4 V0 E) C# c
VideoDeCoder.DEF 文件内容如下' y6 G1 k. f% o4 ^% `) A
2 L, O( Z! j2 e; U% m6 G* c Dump of file VideoDeCoder.dll ; U, C3 t( m+ i# E- c
: T6 m& e, n4 L& n& o; [; g! | File Type: DLL . \, M4 { c( q- m; |
7 O: {% W5 y/ ]5 B) y" U1 f
Section contains the following exports for VideoDeCoder.dll
S# @7 B$ ]# H$ O$ K 4 Q/ V1 r, B0 k1 M( V
0 characteristics
- G& e, k! T8 q$ S5 J/ b 3D49E48F time date stamp Fri Aug 02 09:46:55 2002 $ N$ ?6 k+ c% Z: n/ A4 p D
0.00 version 4 z9 r2 P4 j# G* W1 e3 E: ~
1 ordinal base . p6 A' M/ C7 {: ?
11 number of functions
# i) c3 N2 e6 K5 I1 `! {' Z" V' F 11 number of names 5 u6 R5 z1 R! z
3 R" B1 E- R% s# [ o, N( ^ l2 u
ordinal hint RVA name + z6 s- D0 d5 s2 Z7 s: B
: `$ D4 P: d9 N. ^2 e* D
1 0 00010F60 _TM_ClearDecoderBuff@4 : f0 X6 l1 ?1 x
2 1 00010E80 _TM_CloseDecoder@4 . ^6 a/ ]( O, q
3 2 00010F00 _TM_DecodePicture@4
( N, J3 y$ _" y5 j/ K2 a 4 3 00010ED0 _TM_DecodePictureHeader@4
& y2 q# G, Y$ f7 r7 X 5 4 00010FD0 _TM_GetFileEnd@4
$ x/ \! T; D3 K. Y% A 6 5 00011030 _TM_GetUValue@4
" b/ O7 V4 s; s0 l8 S6 D 7 6 00011060 _TM_GetVValue@4 . @ y9 ~) s, K+ j0 I
8 7 00011000 _TM_GetYValue@4
) r5 s7 r& c4 N9 x 9 8 00010E10 _TM_OpenDecoder@8
6 m3 p7 V# P4 ?' e7 ~" B$ c 10 9 00010F30 _TM_ReturnType@4
3 p/ ]- c- c/ R) g4 F D M 11 A 00010F90 _TM_SetFileEnd@8
; F; H1 _+ W" t0 b ' M8 G0 p" Y/ k& c1 S
Summary ; x, P$ u* l( t; _( U8 X9 i
! L! G6 G& u. \0 ~ X3 W7 j9 { 2000 .data
1 x) J& ?5 o% r8 z4 P 1000 .rdata 6 ] A, F$ ^) c$ r0 Y4 X- r9 m7 w2 J
1000 .reloc ; g0 R f& Q5 W8 l' x" Y# w% ]
15000 .text % s0 L4 }+ H' e6 F
按照以下方法整理:
4 z: n9 Q: n* E, i5 ? 1>添加LIB说明; e( u; _+ j+ s+ d/ H9 ?; s# r* w
LIBRARY "VideoDeCoder" ;"xx"为DLL名称5 N# m7 F/ P3 B/ A' ?/ L
DESCRIPTION "VideoDeCoder library" , `( k6 T2 U/ h6 U0 o E
2>去掉导出函数说明端以外的内容,在LIB说明下添加 "EXPROTS" 说明导出函数
! b7 u5 x9 K9 D LIBRARY "VideoDeCoder"3 p4 \0 C7 i% J
DESCRIPTION "VideoDeCoder library"
6 u2 A& n# y8 F0 ? EXPORTS' M7 @5 P5 l' |" A6 R8 i
ordinal hint RVA name 6 X. G3 b) C5 _6 Y
- U0 r# Y. v" ?
1 0 00010F60 _TM_ClearDecoderBuff@4 2 w" m, ?* E+ g6 X/ V; m
2 1 00010E80 _TM_CloseDecoder@4
" ]7 R8 T3 T) y! M y) c; k 3 2 00010F00 _TM_DecodePicture@ T2 e# B' w" o
4 3 00010ED0 _TM_DecodePictureH
D! G0 @2 H7 X9 s% j 5 4 00010FD0 _TM_GetFileEnd@4
! k) b! T* g: }/ j5 n; C 6 5 00011030 _TM_GetUValue@4
- E e. I6 j: v7 o4 ~* h8 x9 N& j3 j 7 6 00011060 _TM_GetVValue@4
* O* F. \/ s8 X- y% l 8 7 00011000 _TM_GetYValue@4 8 N* r( v7 { O- m
9 8 00010E10 _TM_OpenDecoder@8
0 R2 ]; ?* ?: _" v. s' y 10 9 00010F30 _TM_ReturnType@4
; o5 p5 P' s/ s& H 11 A 00010F90 _TM_SetFileEnd@8 " G8 N2 D. \, I: \; `6 E0 z6 o
3>将所有的函数放至行首,去掉 "hint" 和 "RVA" 数据,留下函数的序号 "ordinal" ,在序号前加上 "@" 符号- K4 y( c6 L- W1 G* P
形成 "_导出函数名@参数字节和 @序号" 此种格式(__stdcall 方式调用导出的函数符号是 "函数名称@参数字节和").
9 z' a& P8 l. r 最后形成.DEF文件如下:
# G' M6 z" x/ G1 Z$ ^ LIBRARY "VideoDeCoder"
E+ w* r+ `& ?8 e! z, q; r DESCRIPTION "VideoDeCoder library"5 |4 J. l8 f# ~3 c
EXPORTS
! h" Q B6 ]! [" I0 ? 4 p6 J9 I: ~8 s ?' K/ u1 L
TM_ClearDecoderBuff@4 @1 + y7 P/ M6 Z% p/ S- A
TM_CloseDecoder@4 @2 & a% Z V' a0 O
TM_DecodePicture@4 @3 4 {( w. h" p9 ~4 D' N
TM_DecodePictureHeader@4 @4
4 x, I! D6 @& l4 Q* ] TM_GetFileEnd@4 @5
7 b R( |$ o: R, ~ TM_GetUValue@4 @6
+ W6 ?- J1 X* } y$ F TM_GetVValue@4 @7
& t; J0 |1 ]' O( ?# C' ?) g TM_GetYValue@4 @8
( S Q% v( Q2 Y b' z" A/ C TM_OpenDecoder@8 @9
! H, k( v( U! W, ?6 c TM_ReturnType@4 @10
s/ s7 d4 }: y' C7 H6 _ TM_SetFileEnd@8 @11 0 P& m* k2 F u: q2 `* P7 [
3. 使用VC++的LIB工具,带/DEF:(.def文件名) /MACHINE:IX86(80X86机器),就输出符合VC++格式的的LIB文件了.
) B6 s! z$ z3 P4 z EXAMPLE:
8 D7 P* u8 I" V, o' u! y) c LIB /DEF:VideoDeCoder.def /MACHINE:IX868 G7 @: s4 g7 p: R! V
4. 接时带上LIB文件链接;注意的是当有些动态库DUMPBIN的只有函数名,无"@nn"的参数格式,如C++Builder写的DLL,输出就只有函数名符号,链接时就会报错:9 M# I" _' X( W
error LNK2002:unresolved external symbol "functionname@nn"% S" E6 h+ d/ n; W$ y
提示程序中引入的函数符号无法识别,这时只要将DEF文件中相应的函数名称改为functionname@nn方式,重新建立
% J6 t2 m7 U; S1 }. Q$ Z2 N. P% G" nLIB,重新链接即可.
+ t8 s2 b& e. f1 i/ v: u' i0 p$ l5 Z' S2 ]
这样就制作成功了符合VC调用方式的LIB了!5 ~- c5 V! c8 q1 ]
参考:MSDN2000
5 `' I) M5 |1 l% g7 b/ q要值得一说的是!BORLAND C++BUILDER有一个很好的工具IMPDEF可以直接将DLL中的函数输出到.DEF文件中,只要做一点点修改就可以成为符合VC的DEF文件!
9 `0 h+ @" ]* T/ k! DIMPDEF xxx.def xxx.dll
7 z4 P) L% B9 N* B( J% o2 ~这种方法只能应用于输出为C格式的__stdcall调用方式经过我的论证有些错误!我利用Borland C++和VC++做论证,发现:/ T4 f( ]/ y/ y4 O$ u
而在C++BUILDER中!
* [8 Y0 V" h( J! n' O" v) L" s__cdecl的函数输出前会带一"_"
5 H% E5 K ?' a1 A7 w# T# i__stdcall无特征,只输出函数名# m) H1 f4 [! M, ^: m; e
__fastcall函数输出前带一"@"
_( D* g* d& @( w: k, I$ ?都无"@nn"后缀格式!
+ E: b! J8 C( a9 n/ W8 @在VC中!* _( d# q, y1 y9 q! H
__cdecl无特征,只输出函数名
: f: s, ~6 N I__stdcall的函数输出前会带一"_"后缀带"@nn". b# X. E! P4 @
__fastcall函数输出前带一"@"后缀带"@nn
4 x# k* {2 q( F; @9 W/ H只要将BC的DEF文件中函数申明格式转换为VC识别的格式就可以利用LIB工具生成LIB;要使用C分格输出(extern "C")才是必须的!而且别忘了在DEF文件中的函数申明不要带“_”啊!:)不然会出现error LNK2001的链接错误! |
|