找回密码
 注册
查看: 4429|回复: 0

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

[复制链接]
发表于 2007-12-20 11:00:22 | 显示全部楼层 |阅读模式
请大家注意!这种方法只能应用于输出为C格式的__stdcall调用方式!
7 v7 b/ c, c  @. u, `* s, i7 I9 [; i( U5 }7 i! d4 z6 Q7 [
1. 使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件
3 r0 l" l8 O. v  h1 {' d5 s EXAMPLE:
2 m" b( i( K8 S) y  DUMPBIN VideoDeCoder.dll /EXPROTS /OUT:VideoDeCoder.def
9 x( {3 y6 z' y- u) `" r ' d* @% I1 ?, ?% U
2. 将导出的.DEF文件整理为一符合.DEF个数的函数导出文件/ ?) l) m" W; `
EXAMPLE:
5 v$ T6 k0 p/ v3 l8 v  VideoDeCoder.DEF 文件内容如下
& l1 c3 @/ s- j- Q/ `                                                                 ( {) @! K" y6 \% W! ~
        Dump of file VideoDeCoder.dll                                 
. m! w0 O) c& d, {! L- G                                                                       $ \, s$ P7 d0 x1 Y
        File Type: DLL                                                
+ y% A. e6 A! e* ^: w+ \* Z                                                                       % J  K' Z0 {0 O+ c; z2 q3 p
          Section contains the following exports for VideoDeCoder.dll  ) Z/ X* Q% n0 {- \5 C
                                                                       
5 C& X) Z+ K5 z8 e                   0 characteristics                                   
$ J4 k. t$ b! c: N: B. B            3D49E48F time date stamp Fri Aug 02 09:46:55 2002          # z. g- B8 z; z- h0 I9 b# `
                0.00 version                                          
0 N$ q) T3 J4 ]+ `                   1 ordinal base                                      
  z, l; X* S8 B9 P% y                  11 number of functions                              
' M' K" d! S) l) M                  11 number of names                                   
$ c$ T) D6 i, O. r7 A                                                                       ( r- b3 F8 [9 W5 R! c* j  P9 E
            ordinal hint RVA      name                                 9 H+ e, J0 c" }2 r1 S) \
                                                                       8 s3 N- b+ E4 D
                  1    0 00010F60 _TM_ClearDecoderBuff@4               
" @4 W- w4 y4 l# b! ?0 R, c                  2    1 00010E80 _TM_CloseDecoder@4                  
% S) r2 P7 y$ M' Z& F9 H                  3    2 00010F00 _TM_DecodePicture@4                  4 B, |) K& S& H" B& }
                  4    3 00010ED0 _TM_DecodePictureHeader@4            
/ A& d0 w3 ^) V2 e, b% S* u                  5    4 00010FD0 _TM_GetFileEnd@4                     * o( M1 [+ u. G8 Q, _% E4 O
                  6    5 00011030 _TM_GetUValue@4                     
1 r' V5 t/ B$ V$ o7 T/ R                  7    6 00011060 _TM_GetVValue@4                     
+ i4 v* B1 B0 Q: h* e& r                  8    7 00011000 _TM_GetYValue@4                      2 h* G+ d+ n- e9 E2 p
                  9    8 00010E10 _TM_OpenDecoder@8                    
8 {, B; Q: }4 J. a3 X                 10    9 00010F30 _TM_ReturnType@4                     + v* A# j/ G8 [* j! T
                 11    A 00010F90 _TM_SetFileEnd@8                     ; c9 ^) A9 d4 n4 _  t
                                                                       
9 D" l$ r8 j; @/ T          Summary                                                      
/ [2 G! q. g& U  k                                                                       0 T4 U5 q4 {' M/ g* v$ K) n
                2000 .data                                             $ A$ }8 U$ u8 t! _4 Z0 N  R; \
                1000 .rdata                                            
* J7 b) C! F4 Q6 }. ~                1000 .reloc                                            & q$ K. Y5 Y% |; W6 H7 _2 T' V+ G0 V
               15000 .text                                             
+ `$ E; k" G) k, d* u" F; C2 }  按照以下方法整理:
* E! d1 I. V3 B* p" R2 R  1>添加LIB说明
; P7 ?# O) ^6 S+ U* {- U, j$ `$ Y# n   LIBRARY "VideoDeCoder"            ;"xx"为DLL名称3 T2 {0 t# |7 Y! l1 B- o; K% |
            DESCRIPTION "VideoDeCoder library"  9 i  T& ^) N# `8 S
        2>去掉导出函数说明端以外的内容,在LIB说明下添加 "EXPROTS" 说明导出函数& h, p! V: u) G4 @4 C
         LIBRARY "VideoDeCoder"/ x' c+ _5 h) W$ M6 I7 o5 @% Q5 A  j) a
   DESCRIPTION "VideoDeCoder library"
/ p! ?: [( j* K   EXPORTS
. i6 ^0 H6 o) b7 ~            ordinal hint RVA      name                          : R+ B) f" q( j; i% P) O
                                                                2 D/ T5 z- R' v
                  1    0 00010F60 _TM_ClearDecoderBuff@4            
4 F. J8 E" B( d6 @6 T9 N                  2    1 00010E80 _TM_CloseDecoder@4            
: g+ r: T' ~6 w) R: [                  3    2 00010F00 _TM_DecodePicture@            * D& o1 k: H" N# g
                  4    3 00010ED0 _TM_DecodePictureH            - L) b7 d* ^7 D9 z$ q" C" D
                  5    4 00010FD0 _TM_GetFileEnd@4              & o* C; S9 e, f6 ]# C0 I
                  6    5 00011030 _TM_GetUValue@4               
$ F( w% K0 E; L% @! V6 y* `                  7    6 00011060 _TM_GetVValue@4               ) _) W7 ?% q4 F6 Z- U
                  8    7 00011000 _TM_GetYValue@4               $ [' j: J* o% y
                  9    8 00010E10 _TM_OpenDecoder@8             , X3 ?: Y/ R$ ^5 H0 R9 Q
                 10    9 00010F30 _TM_ReturnType@4              
& `  p* j  W9 y% X7 R( w- |9 F                 11    A 00010F90 _TM_SetFileEnd@8     
" M7 N- q& |+ F        3>将所有的函数放至行首,去掉 "hint" 和 "RVA" 数据,留下函数的序号 "ordinal" ,在序号前加上 "@" 符号, E7 b! j/ G+ e9 q( @6 \* S& @* c
        形成 "_导出函数名@参数字节和 @序号" 此种格式(__stdcall 方式调用导出的函数符号是 "函数名称@参数字节和").
8 d/ H0 n& y# u$ v* q  R- o        最后形成.DEF文件如下:
. z4 e/ t% n( ~( _: Y        LIBRARY "VideoDeCoder"  x3 O% Q. f5 n( f6 W  T
  DESCRIPTION "VideoDeCoder library") ^& S7 s* }+ w3 {& D
  EXPORTS
+ o5 Y$ L9 T% E5 e      0 M) X- l/ l! R$ `
  TM_ClearDecoderBuff@4             @1    . t# y1 `* k$ f6 u
  TM_CloseDecoder@4                 @2    % E% f0 V: d$ H% y
  TM_DecodePicture@4                @3    1 X5 L4 P& a6 ^' p
  TM_DecodePictureHeader@4          @4   
0 V) r2 L5 r6 w% A( C  ]  TM_GetFileEnd@4                   @5   
  T1 |) _* b- R' z- S7 |; O& o$ [  TM_GetUValue@4                    @6   
2 f" q) X. c; `3 i- p" ~! j3 H  TM_GetVValue@4                    @7   
5 J$ s$ \3 D/ K+ n( G  TM_GetYValue@4                    @8      s+ N! b. T% o7 |& E  z
  TM_OpenDecoder@8                  @9    9 x1 Y9 R/ i! |
  TM_ReturnType@4                  @10   
3 L5 e1 @% f; B. X" j" F+ o  TM_SetFileEnd@8                  @11   
5 z' b9 w0 L  [. G4 Y! V2 e1 P3. 使用VC++的LIB工具,带/DEF:(.def文件名) /MACHINE:IX86(80X86机器),就输出符合VC++格式的的LIB文件了.
# \8 i5 e! k( [9 ?: H EXAMPLE:
( O8 h% u/ j- B7 Q0 E/ s2 s  LIB /DEF:VideoDeCoder.def /MACHINE:IX865 P( j: |7 r* Q2 ]
4. 接时带上LIB文件链接;注意的是当有些动态库DUMPBIN的只有函数名,无"@nn"的参数格式,如C++Builder写的DLL,输出就只有函数名符号,链接时就会报错:
& q7 k3 v' a  U error LNK2002:unresolved external symbol "functionname@nn"( {' z0 y2 {: B
提示程序中引入的函数符号无法识别,这时只要将DEF文件中相应的函数名称改为functionname@nn方式,重新建立. f/ T8 E1 B% i
LIB,重新链接即可.
+ o8 o" ]) Y: c. w2 z
9 O! b2 u2 I( H* R& U- O) F' x  d* u这样就制作成功了符合VC调用方式的LIB了!* }1 Z4 d& ?, f1 r+ Y' S7 j
参考:MSDN2000
) `- ~: Q1 G7 F* g$ G要值得一说的是!BORLAND C++BUILDER有一个很好的工具IMPDEF可以直接将DLL中的函数输出到.DEF文件中,只要做一点点修改就可以成为符合VC的DEF文件!9 u5 i* m1 S( Q1 P+ y/ T$ E. ?
IMPDEF xxx.def xxx.dll, u* ]1 ~- v' W$ |1 L) x/ j1 |" X
这种方法只能应用于输出为C格式的__stdcall调用方式经过我的论证有些错误!我利用Borland C++和VC++做论证,发现:2 g' _4 X( m5 S
而在C++BUILDER中!$ ^8 d  C  s+ U& _. y& O$ y
__cdecl的函数输出前会带一"_"0 e" |" r: N! n) ]! }- g
__stdcall无特征,只输出函数名
; ~% B8 r5 s5 q7 D__fastcall函数输出前带一"@"
) n$ K/ a. r* U) J都无"@nn"后缀格式!5 c0 p) K7 G' Z8 R" R% B
在VC中!
% c9 W" A' J* f# U8 B' i+ Z; x__cdecl无特征,只输出函数名
+ x' l9 m: x6 C4 B__stdcall的函数输出前会带一"_"后缀带"@nn"3 _/ ?$ v9 D' V3 S1 r
__fastcall函数输出前带一"@"后缀带"@nn
5 _0 D+ g* i3 E- }- g) Z只要将BC的DEF文件中函数申明格式转换为VC识别的格式就可以利用LIB工具生成LIB;要使用C分格输出(extern "C")才是必须的!而且别忘了在DEF文件中的函数申明不要带“_”啊!:)不然会出现error LNK2001的链接错误!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-10-1 22:03 , Processed in 0.016804 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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