找回密码
 注册
搜索
查看: 4357|回复: 0

VC中无LIB时的DLL隐式链接,制作与VC++相符合的LIB函数符号输入库

[复制链接]
发表于 2007-12-20 11:00:22 | 显示全部楼层 |阅读模式
请大家注意!这种方法只能应用于输出为C格式的__stdcall调用方式!& `: y: n: n8 Q

9 ^# [0 T; p$ K9 P# a1. 使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件# m, o  I; G* ]5 `
EXAMPLE:
3 a8 ^5 X- \8 \4 H* s  DUMPBIN VideoDeCoder.dll /EXPROTS /OUT:VideoDeCoder.def
8 P8 L, P( b+ G$ O
) G2 `: w1 Z, X6 c5 J- @2. 将导出的.DEF文件整理为一符合.DEF个数的函数导出文件
. {: [" j+ w$ \) \; [ EXAMPLE:& m; l6 J2 I# N# v+ N
  VideoDeCoder.DEF 文件内容如下, q# F1 s  e( f; S( ~
                                                                 
( Q# j2 z2 L" O$ t$ Q* T3 `        Dump of file VideoDeCoder.dll                                  . ]1 h6 Y4 s  J
                                                                       , G0 I, h' O( v) O- G; c
        File Type: DLL                                                
7 r: Y, `% p5 e+ x                                                                       % t4 y2 v$ N- F2 @3 b2 H
          Section contains the following exports for VideoDeCoder.dll    A: \" c3 f6 B5 ^$ n
                                                                       ! K# f0 e. k# o) y$ X3 t
                   0 characteristics                                   9 B6 w6 }% N5 u+ V- o
            3D49E48F time date stamp Fri Aug 02 09:46:55 2002         
- C( Y+ S6 }2 }7 ^+ A                0.00 version                                           & v0 z1 g6 l) I8 d- y5 \
                   1 ordinal base                                      / j: f) N/ E5 o' W$ D
                  11 number of functions                              
: C$ ?% [1 y0 [. f0 s                  11 number of names                                   ' I9 ~! \& a% b/ P
                                                                       
* f' h) N, l- E( |- p6 m            ordinal hint RVA      name                                 
) Y8 ~% B/ S' J8 k" h, [                                                                       / D! Z! K. N! g* b
                  1    0 00010F60 _TM_ClearDecoderBuff@4               8 q  M2 n4 i5 g8 `9 v1 h
                  2    1 00010E80 _TM_CloseDecoder@4                  
/ [' d+ C& T7 a0 O; v& V                  3    2 00010F00 _TM_DecodePicture@4                  
# |0 {: T, [3 V: W# s2 J3 u                  4    3 00010ED0 _TM_DecodePictureHeader@4            
$ E9 t7 S3 i8 X! o6 @0 }" f5 r                  5    4 00010FD0 _TM_GetFileEnd@4                     ; W9 W5 t) B" w" X2 t  [. T. N# D
                  6    5 00011030 _TM_GetUValue@4                      $ B) w& I! i( T) j3 E2 o
                  7    6 00011060 _TM_GetVValue@4                     
4 k" m8 Q! U( U* {2 M) w                  8    7 00011000 _TM_GetYValue@4                      - p3 L- S3 Y* k3 T' H+ u
                  9    8 00010E10 _TM_OpenDecoder@8                    ( L2 u5 M, R/ R+ L; S( I
                 10    9 00010F30 _TM_ReturnType@4                     : y1 {7 s  q: H9 {) E: A6 G/ _- R
                 11    A 00010F90 _TM_SetFileEnd@8                     
; }  Q/ G* {/ t                                                                       , C2 N* A: W1 l  o- v
          Summary                                                      
1 L& s7 B2 x& I- c0 q  K1 T                                                                       - @3 T1 C! B. i+ J' I$ n& m0 O3 p
                2000 .data                                             - D: y4 }5 j( t& O" E
                1000 .rdata                                            
- U2 l7 k% V1 g4 Z0 ^& x: \& E                1000 .reloc                                            
& Z6 V* S- f+ {               15000 .text                                             , q( n  \# U4 P
  按照以下方法整理:- `+ ?: k; m  X$ \3 Y9 P! j7 V
  1>添加LIB说明- K( |% j/ l! `1 K) M5 l
   LIBRARY "VideoDeCoder"            ;"xx"为DLL名称
! U5 y+ {+ P" T) G0 @2 I$ \: D: e            DESCRIPTION "VideoDeCoder library"  
! @& a5 v; b* k9 J; }$ S        2>去掉导出函数说明端以外的内容,在LIB说明下添加 "EXPROTS" 说明导出函数$ k1 n' F4 K* ?6 l; \  b# L* j& }5 `
         LIBRARY "VideoDeCoder"/ [+ z# V) p; ~* p3 F) b; {6 u
   DESCRIPTION "VideoDeCoder library"
; S9 S2 |1 d3 G/ b! i; a3 y   EXPORTS8 `, i  J8 d" T
            ordinal hint RVA      name                          / L% y% L; t% o: H
                                                               
# C0 q) F9 s8 P- g, f                  1    0 00010F60 _TM_ClearDecoderBuff@4            / r, i  I% p1 E+ \- d. ?
                  2    1 00010E80 _TM_CloseDecoder@4            ) b) O6 a0 J# a8 A: O0 v
                  3    2 00010F00 _TM_DecodePicture@            $ d# S9 t# M) {5 l# p) A3 W
                  4    3 00010ED0 _TM_DecodePictureH            7 D4 y  X/ h0 p5 f9 H1 [9 _6 N
                  5    4 00010FD0 _TM_GetFileEnd@4              
$ k4 g  w3 [7 ]                  6    5 00011030 _TM_GetUValue@4               
& E9 n8 R. E8 t5 X+ L; i! x: O' M: k9 Q                  7    6 00011060 _TM_GetVValue@4               
+ ?8 k' n8 f) i                  8    7 00011000 _TM_GetYValue@4               % V& H/ _5 |5 @( V3 O9 I& L  x  x
                  9    8 00010E10 _TM_OpenDecoder@8            
/ W5 U5 X" D& o                 10    9 00010F30 _TM_ReturnType@4              
9 m; a( E7 m% d- w% d. Q/ m2 J4 o                 11    A 00010F90 _TM_SetFileEnd@8     4 d6 b. D% Q6 u5 i( M
        3>将所有的函数放至行首,去掉 "hint" 和 "RVA" 数据,留下函数的序号 "ordinal" ,在序号前加上 "@" 符号  P# G- |* s/ M2 O
        形成 "_导出函数名@参数字节和 @序号" 此种格式(__stdcall 方式调用导出的函数符号是 "函数名称@参数字节和").6 x, _. X5 {+ [
        最后形成.DEF文件如下:
1 F. C7 v6 T7 T3 g: G; @  c% h        LIBRARY "VideoDeCoder"
; j9 z9 Y- `) w) q( ~, n  DESCRIPTION "VideoDeCoder library"5 h! @, _1 R. E$ |) u' G6 a
  EXPORTS
2 \; R7 C$ W% e% ]      ; |( M" }- z7 _- O: o
  TM_ClearDecoderBuff@4             @1   
- y- x  {. K4 g, V: d; n* d- U9 z  TM_CloseDecoder@4                 @2   
! Y) f! U; C  M( r( g+ _* G/ u) S  TM_DecodePicture@4                @3   
4 k- ]5 x4 ^+ d* d; R4 c* _0 ]  [  TM_DecodePictureHeader@4          @4    2 N3 `& V* ^- v' M( d
  TM_GetFileEnd@4                   @5    " U, r) i1 x9 Q- e2 h* J6 F
  TM_GetUValue@4                    @6   
# b. u& Y! R# ~5 \  TM_GetVValue@4                    @7    * s% D9 D2 X: q+ K* q
  TM_GetYValue@4                    @8   
: Z: D* v. }8 b! f  TM_OpenDecoder@8                  @9    : {: P4 g) @. C9 r
  TM_ReturnType@4                  @10   
# j5 Y( L  _' Z1 d  TM_SetFileEnd@8                  @11   
9 l! S: q0 X9 X7 {: H8 h- A3. 使用VC++的LIB工具,带/DEF:(.def文件名) /MACHINE:IX86(80X86机器),就输出符合VC++格式的的LIB文件了.
, X2 [" @# C) ?3 ] EXAMPLE:# J1 f9 A( p- R. e/ u
  LIB /DEF:VideoDeCoder.def /MACHINE:IX86$ q8 K1 B" k' E1 g) p
4. 接时带上LIB文件链接;注意的是当有些动态库DUMPBIN的只有函数名,无"@nn"的参数格式,如C++Builder写的DLL,输出就只有函数名符号,链接时就会报错:2 R& O- q" {. `1 S1 o6 h1 n' \4 r
error LNK2002:unresolved external symbol "functionname@nn"
% ~& S7 ?& g0 Z3 d3 _/ }提示程序中引入的函数符号无法识别,这时只要将DEF文件中相应的函数名称改为functionname@nn方式,重新建立$ R0 q3 J& [  S" [& @! i
LIB,重新链接即可.& u; `+ E+ T) h/ I' ~& F& ]

! Z. l& T1 j3 A  [这样就制作成功了符合VC调用方式的LIB了!
1 N  I2 ^  x: V! v6 u9 }参考:MSDN2000
0 W. c! B% t$ s. W8 x要值得一说的是!BORLAND C++BUILDER有一个很好的工具IMPDEF可以直接将DLL中的函数输出到.DEF文件中,只要做一点点修改就可以成为符合VC的DEF文件!; t, g9 B( m6 D+ p
IMPDEF xxx.def xxx.dll8 B9 v4 `( A1 d. q
这种方法只能应用于输出为C格式的__stdcall调用方式经过我的论证有些错误!我利用Borland C++和VC++做论证,发现:
7 A6 x4 F7 s3 [2 a3 G9 H而在C++BUILDER中!
9 \" Z( `) k9 {* I  F8 p/ u__cdecl的函数输出前会带一"_"
9 ^  s" \* [# j__stdcall无特征,只输出函数名, |8 c, z9 K* O1 V! L, ^
__fastcall函数输出前带一"@"/ T1 \9 T* D5 H6 y
都无"@nn"后缀格式!+ @: N, \4 c. b$ h$ p2 o6 b# a9 }
在VC中!
" L! E" \7 Q& l" Q/ f' \+ M__cdecl无特征,只输出函数名1 K3 I" B. `/ r, v0 ~" i
__stdcall的函数输出前会带一"_"后缀带"@nn"% ^2 ^. m8 H5 J" p3 \
__fastcall函数输出前带一"@"后缀带"@nn
4 W$ i8 L- R; @' K: s. v- a# M$ Z只要将BC的DEF文件中函数申明格式转换为VC识别的格式就可以利用LIB工具生成LIB;要使用C分格输出(extern "C")才是必须的!而且别忘了在DEF文件中的函数申明不要带“_”啊!:)不然会出现error LNK2001的链接错误!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2026-6-18 10:49 , Processed in 0.019418 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表