|
请大家注意!这种方法只能应用于输出为C格式的__stdcall调用方式!
0 n' b4 c. P: G- n
. ]% A5 `8 L: ]% A; s1. 使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件; F2 `( _' I) N+ j0 {
EXAMPLE:$ {2 N" n- D4 R9 S5 L
DUMPBIN VideoDeCoder.dll /EXPROTS /OUT:VideoDeCoder.def
! m; q. p8 U9 o4 I' m
# @" C+ M: y9 N& w# V# B2. 将导出的.DEF文件整理为一符合.DEF个数的函数导出文件
" r0 F1 I* q) F/ q/ } EXAMPLE:. l5 i+ z& H9 e. {! a1 f. N
VideoDeCoder.DEF 文件内容如下
6 N: ^% R1 O4 z) b ^ ! z* Y$ V% W5 D
Dump of file VideoDeCoder.dll
, {! k3 e. M* K- ~
/ [, `% c# r: i/ g6 d# ` File Type: DLL & `" D5 t" e5 ?
) j7 B9 B4 z: l( ^$ M/ A
Section contains the following exports for VideoDeCoder.dll
; O0 D: Y6 Z! O# V* c1 u
; |' l5 m5 L6 a* w2 n8 n 0 characteristics
$ e b+ f( ]2 G5 x, R G; I9 c 3D49E48F time date stamp Fri Aug 02 09:46:55 2002
3 q( m2 }8 Z& \$ N1 n# B0 v7 I9 b5 e 0.00 version / p: V$ c5 P- P1 i) j" G% G
1 ordinal base 3 U+ v2 `" y; `5 c! Z
11 number of functions
5 x/ f: y6 M6 z 11 number of names
( C; M! {' f6 l. k6 E8 b
" _3 }) @" L$ T ordinal hint RVA name 8 k2 R! h5 Q# y5 f4 d: ?, M' v
, F' @* k7 x! q% ~ 1 0 00010F60 _TM_ClearDecoderBuff@4
' J! q9 e. H& @4 V" | 2 1 00010E80 _TM_CloseDecoder@4
1 q$ u8 u, v; Z- E1 n$ y 3 2 00010F00 _TM_DecodePicture@4 1 U: p& g; G7 K. j- J
4 3 00010ED0 _TM_DecodePictureHeader@4 " ~5 u# n9 a1 ]7 h
5 4 00010FD0 _TM_GetFileEnd@4
( N- \" L) N1 E 6 5 00011030 _TM_GetUValue@4 D; v# Q* E" u
7 6 00011060 _TM_GetVValue@4 / N/ s4 u1 z$ [, @# m: @6 X) g( M
8 7 00011000 _TM_GetYValue@4 8 L# P0 e( U+ v
9 8 00010E10 _TM_OpenDecoder@8
0 }0 h& m6 Z* l5 A' j' ^% X/ j" V: v 10 9 00010F30 _TM_ReturnType@4
1 ]- k( d4 ^9 d 11 A 00010F90 _TM_SetFileEnd@8 # p+ t/ ]4 v7 z" T. Y% E
) M! Z* ?% U1 ~) \. Q
Summary & Q/ ?" }5 k' |# e- k, V
3 G& {7 r/ W8 Z9 e
2000 .data / ?* G! b2 L& [! c( R0 Q6 u
1000 .rdata 4 R2 A5 m/ e u
1000 .reloc " C7 U8 D! N- ~7 L5 r, y
15000 .text : Q5 }6 T! l5 a8 r3 O
按照以下方法整理:
2 p2 @6 `7 T7 F# Y" N. E& ? 1>添加LIB说明
" l: Y' k& F8 y5 L LIBRARY "VideoDeCoder" ;"xx"为DLL名称/ h% ?/ S- {$ F/ W4 r
DESCRIPTION "VideoDeCoder library"
- Z( l0 z# R& i; M 2>去掉导出函数说明端以外的内容,在LIB说明下添加 "EXPROTS" 说明导出函数
" i* n6 r% n/ o4 O- A$ i; z LIBRARY "VideoDeCoder"; E. G. v, M5 `! B- t% d
DESCRIPTION "VideoDeCoder library"( o* v4 m* a$ ~2 f! I7 g- N
EXPORTS
- g+ U; T7 T8 T/ r9 g- u& B ordinal hint RVA name
" \& g; C. ~2 k! t! M$ z z
/ B$ {& U7 ^5 n 1 0 00010F60 _TM_ClearDecoderBuff@4 8 e* Y* ^" F( g$ v' j0 l
2 1 00010E80 _TM_CloseDecoder@4 3 M) L+ v; @* D
3 2 00010F00 _TM_DecodePicture@
4 T4 E/ U/ t) k 4 3 00010ED0 _TM_DecodePictureH " A1 q, o" Q) T0 h( Y
5 4 00010FD0 _TM_GetFileEnd@4
, S; y6 {% M+ ]* N$ a( m5 @% { 6 5 00011030 _TM_GetUValue@4 ! Y' m, f7 z# E9 ]0 j$ y
7 6 00011060 _TM_GetVValue@4 % Y% ?" n7 G$ {- g! }1 p# k
8 7 00011000 _TM_GetYValue@4
. z/ G7 D* \( }5 x: ] 9 8 00010E10 _TM_OpenDecoder@8 : e' ]; x% F! e7 k" x- j0 e' }
10 9 00010F30 _TM_ReturnType@4
5 W& R5 z$ O$ E8 F) D% O 11 A 00010F90 _TM_SetFileEnd@8 ) W$ O6 C* y+ D
3>将所有的函数放至行首,去掉 "hint" 和 "RVA" 数据,留下函数的序号 "ordinal" ,在序号前加上 "@" 符号
! s( `& j0 o5 h2 m 形成 "_导出函数名@参数字节和 @序号" 此种格式(__stdcall 方式调用导出的函数符号是 "函数名称@参数字节和").
& Q8 t* a5 f0 q' [6 s 最后形成.DEF文件如下:' i/ F5 f; L1 x( [/ S3 C3 |
LIBRARY "VideoDeCoder": b6 C- P* r+ F
DESCRIPTION "VideoDeCoder library"
& I( ^6 D- p6 e# u EXPORTS
! l5 j- `. ?! a/ o9 g' y 2 N) J! W3 S& ^" j' i- c9 z
TM_ClearDecoderBuff@4 @1
; e/ J7 b% X; n/ m TM_CloseDecoder@4 @2 ; t0 \. [% r! c7 P
TM_DecodePicture@4 @3
5 {% } h2 ~/ T3 X, e$ I TM_DecodePictureHeader@4 @4
$ X* o5 X/ K' _9 { TM_GetFileEnd@4 @5
r! `% k9 d5 H TM_GetUValue@4 @6
- @/ l) `/ w8 b TM_GetVValue@4 @7
a2 ~' y5 S+ {. \4 j% s TM_GetYValue@4 @8
# s1 j/ k. Y4 Y6 \ TM_OpenDecoder@8 @9
5 m4 A- N: T4 c TM_ReturnType@4 @10 6 ^! C3 v4 l, J$ `
TM_SetFileEnd@8 @11
$ n: \# I- ]" q8 c% x3. 使用VC++的LIB工具,带/DEF:(.def文件名) /MACHINE:IX86(80X86机器),就输出符合VC++格式的的LIB文件了.
9 \+ f7 M' }2 Z: \( M1 i9 F EXAMPLE:
5 I5 k* T2 Z4 |8 W. k LIB /DEF:VideoDeCoder.def /MACHINE:IX86- i G( H* X3 y/ S9 }
4. 接时带上LIB文件链接;注意的是当有些动态库DUMPBIN的只有函数名,无"@nn"的参数格式,如C++Builder写的DLL,输出就只有函数名符号,链接时就会报错: v% L, j, ^$ R8 R2 V
error LNK2002:unresolved external symbol "functionname@nn"- }# R% T4 Y6 }2 W
提示程序中引入的函数符号无法识别,这时只要将DEF文件中相应的函数名称改为functionname@nn方式,重新建立8 D$ ~, o b& E- `+ v
LIB,重新链接即可.
7 }. B* j6 |1 T9 _0 n% D. H$ X* A. T* f( Q! m
这样就制作成功了符合VC调用方式的LIB了!5 P- q! e* S/ Y, l `6 S0 m
参考:MSDN2000
6 L- S- K1 B! u要值得一说的是!BORLAND C++BUILDER有一个很好的工具IMPDEF可以直接将DLL中的函数输出到.DEF文件中,只要做一点点修改就可以成为符合VC的DEF文件!
$ a, s2 t/ O/ [4 ]IMPDEF xxx.def xxx.dll
- W; f: ~, x- s1 J0 M这种方法只能应用于输出为C格式的__stdcall调用方式经过我的论证有些错误!我利用Borland C++和VC++做论证,发现:7 g4 e6 L4 \% ]
而在C++BUILDER中!
6 o8 V% s J4 ]2 n__cdecl的函数输出前会带一"_"; i, Q' y" U$ p% U
__stdcall无特征,只输出函数名) j$ S& R1 D+ }8 X0 F" m
__fastcall函数输出前带一"@"
7 ~1 r$ H' }4 Y& g9 a d( z3 `都无"@nn"后缀格式!
5 s+ |! s0 g/ k* R5 |% X在VC中!
2 R0 h# l8 j# E( T% I I" K' K# p5 v__cdecl无特征,只输出函数名
6 u; ~$ Y2 s* Q5 K- S+ K__stdcall的函数输出前会带一"_"后缀带"@nn"
* F5 |3 p! b E1 t) C0 Y5 [__fastcall函数输出前带一"@"后缀带"@nn) \7 n+ S$ Q6 A f( `" ~, J
只要将BC的DEF文件中函数申明格式转换为VC识别的格式就可以利用LIB工具生成LIB;要使用C分格输出(extern "C")才是必须的!而且别忘了在DEF文件中的函数申明不要带“_”啊!:)不然会出现error LNK2001的链接错误! |
|