|
|
请大家注意!这种方法只能应用于输出为C格式的__stdcall调用方式!) A. n. F$ s* z1 M
4 P9 \+ t% g2 h. V0 i! ^7 n0 h1. 使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件6 [4 U- m8 N2 L9 G
EXAMPLE:
; F& R7 Z' H2 }% M7 M! ^1 P- v9 e DUMPBIN VideoDeCoder.dll /EXPROTS /OUT:VideoDeCoder.def
! n1 x# I3 u9 p, t0 N, E# F; ]
6 t" }; z# O$ l' ^: F. u! k- ~2. 将导出的.DEF文件整理为一符合.DEF个数的函数导出文件, j( [6 X2 A% T0 I; g1 Z) b
EXAMPLE:) l1 X+ g1 V3 `+ S8 g* d
VideoDeCoder.DEF 文件内容如下5 g0 ^4 E4 f0 d4 z+ w2 ]; ]$ Q; i+ X
0 x: Y2 o& k( r Dump of file VideoDeCoder.dll $ q9 S, d4 Z* b# f1 h! G9 q/ _, n
* p# v4 G/ R' K
File Type: DLL
" k/ F9 E8 i; {8 @" ] ! V. n5 z* u5 X& N% D3 i
Section contains the following exports for VideoDeCoder.dll . N- H" m1 f( F) p( b# X
0 J& t$ B! d* Z2 f; |0 |
0 characteristics
# N! x+ O, k3 u* N4 t3 Q 3D49E48F time date stamp Fri Aug 02 09:46:55 2002 . X. A1 M3 E j" P& A4 i6 a7 f
0.00 version
* P2 H3 ]" n7 e1 Q, Q1 s- w+ m 1 ordinal base 1 f( @0 |7 p8 z4 [8 Z
11 number of functions 1 K1 f8 l# S7 k) Y
11 number of names
' {- T- H9 l6 k" U- b# b4 Y
3 z* g; I; r+ B, U# I s7 s2 Z+ p ordinal hint RVA name 0 _3 g7 _& Q' b2 u- {9 f6 B
3 \8 ?- k: `: o" C" \- R% W 1 0 00010F60 _TM_ClearDecoderBuff@4
/ a* k! l2 J Y$ [' y 2 1 00010E80 _TM_CloseDecoder@4
6 M! |) }: Q7 a 3 2 00010F00 _TM_DecodePicture@4 . E% t7 S m4 R# q/ r0 `
4 3 00010ED0 _TM_DecodePictureHeader@4 & W% i u4 [ C! y5 H8 ^# O' Y
5 4 00010FD0 _TM_GetFileEnd@4
, [5 y6 n2 R5 E) V4 T 6 5 00011030 _TM_GetUValue@4
" O: G# V# D' B. |5 v4 i8 j& u( Z 7 6 00011060 _TM_GetVValue@4
8 N. B8 a6 {$ s% H 8 7 00011000 _TM_GetYValue@4 % C b5 G" ]" h9 G/ X* `
9 8 00010E10 _TM_OpenDecoder@8
( d* X+ P: g1 Y; _( _2 J 10 9 00010F30 _TM_ReturnType@4 6 Z% ]( e4 E' E' { [/ u1 k( L
11 A 00010F90 _TM_SetFileEnd@8
# ~* z! C/ x! ?# c9 q# X
f& X& V/ d5 d$ ~* H Summary 8 u+ k( T. r M
# s) ^/ l& w: N% S8 M 2000 .data ! h! s) w% {" P
1000 .rdata
- V# z" B. ^+ V4 n2 o5 g) p6 e 1000 .reloc
( e9 N. q, p4 |& O- R! z* E 15000 .text + W) \4 ^6 A) V- G2 F: H: [0 @ W/ s
按照以下方法整理:# g: r* I# Q9 `( N! Q0 u9 F! `& I
1>添加LIB说明. q+ y+ F# N. d! m
LIBRARY "VideoDeCoder" ;"xx"为DLL名称
! s. S' r5 I! o l; n/ @& H DESCRIPTION "VideoDeCoder library"
. F# A4 k) @# C5 ? 2>去掉导出函数说明端以外的内容,在LIB说明下添加 "EXPROTS" 说明导出函数8 H0 Q/ ` o1 d2 ^- R0 F# U! O" @
LIBRARY "VideoDeCoder"
e' ^' P" |4 m DESCRIPTION "VideoDeCoder library"
& {9 i, p/ Y& N& w& W; {8 g EXPORTS4 N4 {) y8 M9 v0 p
ordinal hint RVA name , Q. ?3 a2 x1 d4 O5 `
/ L: W! L' d' P# D: }( Y* b" g
1 0 00010F60 _TM_ClearDecoderBuff@4
6 W" t& z/ ^( ]* X' b0 ^ 2 1 00010E80 _TM_CloseDecoder@4
& p% ^1 t B1 z8 u' ~, S& w 3 2 00010F00 _TM_DecodePicture@
8 D# f$ S9 B* E: A* Y 4 3 00010ED0 _TM_DecodePictureH
! O* d% q* C' v. e( I: \: | 5 4 00010FD0 _TM_GetFileEnd@4 # b6 \" B5 T3 p
6 5 00011030 _TM_GetUValue@4 ' X& n6 x7 w' W! L$ j5 c
7 6 00011060 _TM_GetVValue@4
) R$ Q& I9 O$ w6 G K) H 8 7 00011000 _TM_GetYValue@4
5 f; B, k, _1 k 9 8 00010E10 _TM_OpenDecoder@8 $ `* }, d& H: d/ r: _
10 9 00010F30 _TM_ReturnType@4
4 S7 t' h$ N9 o 11 A 00010F90 _TM_SetFileEnd@8 ( y+ e& | U8 U3 B5 k6 p
3>将所有的函数放至行首,去掉 "hint" 和 "RVA" 数据,留下函数的序号 "ordinal" ,在序号前加上 "@" 符号
- }8 u' O8 v! [* n) b7 H; j# K/ ~ 形成 "_导出函数名@参数字节和 @序号" 此种格式(__stdcall 方式调用导出的函数符号是 "函数名称@参数字节和").! [& h$ w4 J5 [: F
最后形成.DEF文件如下:! `' B; w% y2 W- W* P+ \" n9 v
LIBRARY "VideoDeCoder"
& i( h' Z6 `3 W" c5 F DESCRIPTION "VideoDeCoder library"
+ p' m5 J' Y/ b EXPORTS0 M) k! I/ E( S9 l7 t u- C. R0 Z
# h2 m& \( l Y0 p TM_ClearDecoderBuff@4 @1
- Y B4 a# F/ `4 h" o; K TM_CloseDecoder@4 @2
9 z6 o* m# k! B2 k% f TM_DecodePicture@4 @3
, [" ~9 o$ \: ^ ]/ ~8 J) c7 f$ S( r TM_DecodePictureHeader@4 @4 1 {5 I* K! a% e- ?
TM_GetFileEnd@4 @5 $ d6 g: Y) p) S7 y
TM_GetUValue@4 @6
: {* ~- e" C8 u9 ^" p3 J TM_GetVValue@4 @7 ! |4 @$ g2 c" Y- {
TM_GetYValue@4 @8 5 c6 D1 F; L1 J! X: T3 ?
TM_OpenDecoder@8 @9 0 x) a8 i9 [0 U; f' E' k
TM_ReturnType@4 @10
0 l: B; n1 r+ N$ Q8 n7 p) D E TM_SetFileEnd@8 @11 / K9 \6 I6 P7 j# g
3. 使用VC++的LIB工具,带/DEF:(.def文件名) /MACHINE:IX86(80X86机器),就输出符合VC++格式的的LIB文件了./ g C. T6 R* U- u2 a& D
EXAMPLE:
% u8 _6 I4 p2 P4 O LIB /DEF:VideoDeCoder.def /MACHINE:IX86# y: Q% n7 ?2 I7 c' g# E
4. 接时带上LIB文件链接;注意的是当有些动态库DUMPBIN的只有函数名,无"@nn"的参数格式,如C++Builder写的DLL,输出就只有函数名符号,链接时就会报错:
6 ]& O b2 P4 k* e1 m7 b. j error LNK2002:unresolved external symbol "functionname@nn"
6 W& B. I! X( E7 w提示程序中引入的函数符号无法识别,这时只要将DEF文件中相应的函数名称改为functionname@nn方式,重新建立3 h a {3 h1 s% t' |. y2 N) e
LIB,重新链接即可.2 g) i! q* |! U5 W" M/ q
/ l1 b [ g" M/ K这样就制作成功了符合VC调用方式的LIB了!
7 ^2 ]# o% r8 ?- _参考:MSDN2000
& `3 J4 T; y0 V5 o: o要值得一说的是!BORLAND C++BUILDER有一个很好的工具IMPDEF可以直接将DLL中的函数输出到.DEF文件中,只要做一点点修改就可以成为符合VC的DEF文件!
; i5 J0 J, Q5 q* `! h* ZIMPDEF xxx.def xxx.dll, Y& Z% E8 X; O8 j: l# Q4 h
这种方法只能应用于输出为C格式的__stdcall调用方式经过我的论证有些错误!我利用Borland C++和VC++做论证,发现:
1 A. x4 P" p$ t* X而在C++BUILDER中!
8 N5 b7 S8 I) I) K5 I. D% W__cdecl的函数输出前会带一"_"
4 T2 G% r) I; g* }7 Z0 z__stdcall无特征,只输出函数名
/ h3 `9 n) C% _) P0 R3 Y__fastcall函数输出前带一"@"# Q! e) Y+ W/ b
都无"@nn"后缀格式!
6 [0 F% L" w7 i3 Q8 {& s在VC中!
- m' j- C+ R2 b5 T3 b& v% V__cdecl无特征,只输出函数名% p; p, n+ k/ ^& `( J
__stdcall的函数输出前会带一"_"后缀带"@nn"; x5 r4 \" K) I3 M! }$ `
__fastcall函数输出前带一"@"后缀带"@nn4 G2 x. A0 m- Q$ Z1 v, U3 @3 k% b
只要将BC的DEF文件中函数申明格式转换为VC识别的格式就可以利用LIB工具生成LIB;要使用C分格输出(extern "C")才是必须的!而且别忘了在DEF文件中的函数申明不要带“_”啊!:)不然会出现error LNK2001的链接错误! |
|