|
|
请大家注意!这种方法只能应用于输出为C格式的__stdcall调用方式!
, `. h% r. x, Q: J
/ e' m1 h/ U0 p/ \1. 使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件
. ^- m- E$ R. S# \; b1 h# R EXAMPLE:# E+ X% i t' j
DUMPBIN VideoDeCoder.dll /EXPROTS /OUT:VideoDeCoder.def
% s8 ]9 o/ V* f4 N $ s0 Z! S, I' T# S
2. 将导出的.DEF文件整理为一符合.DEF个数的函数导出文件/ D" R- C) v4 L0 p# Z! s, ]
EXAMPLE: D4 k; ^) z# t8 X
VideoDeCoder.DEF 文件内容如下% \+ f; K+ F" @2 G" X6 r
; v- @4 j Y# y. { Dump of file VideoDeCoder.dll , |% z7 i ^/ Y) I' e' j2 N; x
2 f/ _' O3 d; }( E1 q& v* E6 _
File Type: DLL
7 U+ x0 Q$ P8 H4 f$ `+ X8 l- v4 p8 i/ M1 O
1 s8 y. m! a. U7 D( {5 ~ Section contains the following exports for VideoDeCoder.dll
9 A2 T' j1 X1 Y( {$ b+ p9 U) q L6 s/ d, F2 C% E( M% v
0 characteristics
9 X6 Q. N& Y) e f 3D49E48F time date stamp Fri Aug 02 09:46:55 2002
. I/ x$ O% F% u$ p, y8 ?' w* \. b 0.00 version
3 G% c1 L' j* L$ h! ^9 y 1 ordinal base
) f$ r) U2 q3 X+ h7 o 11 number of functions
! ~4 V1 G" ~* G2 a 11 number of names 4 b* T6 [( q; ^- D. H
0 ^$ G8 X4 b5 m, q
ordinal hint RVA name ( K8 Y' O) f- l5 Y
: Z, I. y; s1 w+ j& W 1 0 00010F60 _TM_ClearDecoderBuff@4
2 A+ l8 G, _# z3 I/ H3 Z+ b 2 1 00010E80 _TM_CloseDecoder@4 2 ~& R+ e- c3 J% D, v
3 2 00010F00 _TM_DecodePicture@4 + m% u7 D. L6 ^1 k: v, y% J- H
4 3 00010ED0 _TM_DecodePictureHeader@4
' G9 l; u8 \+ m9 \7 @4 ] 5 4 00010FD0 _TM_GetFileEnd@4 # j5 ?0 {3 C) a. b3 ` T
6 5 00011030 _TM_GetUValue@4 5 v& _/ A: |0 N4 i, V* ]
7 6 00011060 _TM_GetVValue@4
2 U0 N1 {3 c4 G* Q8 Z( h5 H! } 8 7 00011000 _TM_GetYValue@4
% H+ o3 U( a" k0 g 9 8 00010E10 _TM_OpenDecoder@8
& e; r% T+ u& q' y 10 9 00010F30 _TM_ReturnType@4 7 R7 T6 x+ p! ]
11 A 00010F90 _TM_SetFileEnd@8
; r- J0 a$ I" A: e9 e( Y
( C7 H1 y0 p; t K! I& ? Summary
2 e( x0 C9 c8 l
S4 V$ y* Z' I- G 2000 .data # m0 [/ U: ]1 }: N, ~0 Y6 H& _
1000 .rdata + U, \. X8 |+ m0 O, E
1000 .reloc
1 k7 G! n1 g" o, y9 N# A 15000 .text 6 |7 i. `% |' y( X. G
按照以下方法整理:
/ l) U# L( `& y$ R7 b 1>添加LIB说明
0 U4 w6 d; x1 b LIBRARY "VideoDeCoder" ;"xx"为DLL名称
1 H V; C G6 |8 o1 K$ U DESCRIPTION "VideoDeCoder library"
" N$ p( m' x+ x0 _* P8 N. p* I0 l 2>去掉导出函数说明端以外的内容,在LIB说明下添加 "EXPROTS" 说明导出函数
( }- q8 p7 x) ?. {# Q6 H0 z) l/ Q LIBRARY "VideoDeCoder"
~! c; M3 {, p0 ^. b/ ^ DESCRIPTION "VideoDeCoder library"
9 D7 X+ C* b- {4 ` EXPORTS% Q$ W/ K2 K5 u9 q( {5 }
ordinal hint RVA name 5 W) I5 ~1 H# L
0 t; J% R0 l. y# ~2 x7 p$ U 1 0 00010F60 _TM_ClearDecoderBuff@4 8 r3 w1 Y0 m; x4 P1 E0 | U* S
2 1 00010E80 _TM_CloseDecoder@4
; u2 \' B1 R, t& I7 \ 3 2 00010F00 _TM_DecodePicture@
2 _% R) \ ?" w# I 4 3 00010ED0 _TM_DecodePictureH
& b( L5 x, J% ^1 F0 t 5 4 00010FD0 _TM_GetFileEnd@4 - i, b1 X( T! Y# }
6 5 00011030 _TM_GetUValue@4
6 @$ N6 C0 E; i 7 6 00011060 _TM_GetVValue@4 - L* o N; O9 N' K2 W. h4 J
8 7 00011000 _TM_GetYValue@4
/ s' B3 F Y1 Y- E 9 8 00010E10 _TM_OpenDecoder@8
' y4 y: n r: j9 j5 h' W 10 9 00010F30 _TM_ReturnType@4
- I( ]9 U2 L0 O( C% { 11 A 00010F90 _TM_SetFileEnd@8
4 r' O( q* [# C& A# S3 | 3>将所有的函数放至行首,去掉 "hint" 和 "RVA" 数据,留下函数的序号 "ordinal" ,在序号前加上 "@" 符号8 S! n8 d3 c" b
形成 "_导出函数名@参数字节和 @序号" 此种格式(__stdcall 方式调用导出的函数符号是 "函数名称@参数字节和").: w6 f4 |/ ~1 o5 i& g
最后形成.DEF文件如下:
" m0 b' p0 G5 Y1 ^+ a4 Z LIBRARY "VideoDeCoder"
9 @+ ? C/ |$ C7 G% d9 l. m# A k DESCRIPTION "VideoDeCoder library"
' o9 u4 @8 {; `$ a EXPORTS
) V6 D9 b% }8 k1 ~; B8 \! X 8 c4 L+ X* P- h7 m- f/ @& B! A `( t. h
TM_ClearDecoderBuff@4 @1 . c& C" Y/ k4 H$ u7 i- p" w9 @6 Z
TM_CloseDecoder@4 @2 $ g8 B6 T$ s& b! ?' j6 J
TM_DecodePicture@4 @3 5 Y7 Y4 h5 \ P2 @* U# ]
TM_DecodePictureHeader@4 @4
$ h$ v: M) P5 h( |% J TM_GetFileEnd@4 @5 3 {& @! @( v; ^! u
TM_GetUValue@4 @6
: i5 r) X5 q: V. ?" o TM_GetVValue@4 @7
: G2 J5 E) g4 v- K q TM_GetYValue@4 @8
# l/ O# S3 V% m% w. ^, [ TM_OpenDecoder@8 @9
/ M3 N4 I& J6 Z. @; d TM_ReturnType@4 @10 0 M1 M& X* A# l0 M. l
TM_SetFileEnd@8 @11 , B$ L" D$ A. H8 I' U( u+ d
3. 使用VC++的LIB工具,带/DEF:(.def文件名) /MACHINE:IX86(80X86机器),就输出符合VC++格式的的LIB文件了.
- l1 ]/ d8 X4 e* D- q EXAMPLE:
( @. u" q: V! g' I LIB /DEF:VideoDeCoder.def /MACHINE:IX86
0 m' h ?9 z$ p* ~9 |/ ?4. 接时带上LIB文件链接;注意的是当有些动态库DUMPBIN的只有函数名,无"@nn"的参数格式,如C++Builder写的DLL,输出就只有函数名符号,链接时就会报错:
# x3 A9 X6 B9 `8 O" X, B error LNK2002:unresolved external symbol "functionname@nn"
; \; U: M! k6 q) B4 d, w提示程序中引入的函数符号无法识别,这时只要将DEF文件中相应的函数名称改为functionname@nn方式,重新建立2 F" O0 l/ O- l7 s; s+ Y! p
LIB,重新链接即可.
* z6 d- B- M5 k8 k5 x% g" d6 ^6 D1 y0 \4 g1 O' l
这样就制作成功了符合VC调用方式的LIB了!2 y+ S# Q4 h9 G4 D0 k5 ?
参考:MSDN20003 u1 s6 q+ C R! x" R# O0 L; p
要值得一说的是!BORLAND C++BUILDER有一个很好的工具IMPDEF可以直接将DLL中的函数输出到.DEF文件中,只要做一点点修改就可以成为符合VC的DEF文件!
) w5 t5 E5 I% L* KIMPDEF xxx.def xxx.dll8 i/ F7 m( G" t7 C5 s
这种方法只能应用于输出为C格式的__stdcall调用方式经过我的论证有些错误!我利用Borland C++和VC++做论证,发现:
- X# \' B4 M6 o& V2 V4 M而在C++BUILDER中!
5 \6 ]6 i# J" x- I__cdecl的函数输出前会带一"_"- ?- D3 h R3 v
__stdcall无特征,只输出函数名
: N+ f e2 _# c' J! T__fastcall函数输出前带一"@"
. ^7 v& A5 i6 c, C3 N0 n都无"@nn"后缀格式!( E5 m: ~ }% h; k* [
在VC中! r" L# l% o* r
__cdecl无特征,只输出函数名 ^) ^6 h l8 { d# L
__stdcall的函数输出前会带一"_"后缀带"@nn"
; ^& L) y/ ]5 b% n' N- `__fastcall函数输出前带一"@"后缀带"@nn2 y: ^' [9 \% ?
只要将BC的DEF文件中函数申明格式转换为VC识别的格式就可以利用LIB工具生成LIB;要使用C分格输出(extern "C")才是必须的!而且别忘了在DEF文件中的函数申明不要带“_”啊!:)不然会出现error LNK2001的链接错误! |
|