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

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

[复制链接]
发表于 2007-12-20 11:00:22 | 显示全部楼层 |阅读模式
请大家注意!这种方法只能应用于输出为C格式的__stdcall调用方式!
. y3 _+ d' V5 d& C6 C" P" d5 S1 r/ ?3 J; @! R
1. 使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件
- {0 }, i; E! ~: l( ?9 l8 V7 D  K* v EXAMPLE:
# R2 E9 s( |1 [  DUMPBIN VideoDeCoder.dll /EXPROTS /OUT:VideoDeCoder.def4 R* W. z# h8 J+ q" V# V5 j

+ C1 L& e4 p6 {5 Q& @" V2. 将导出的.DEF文件整理为一符合.DEF个数的函数导出文件
' ?! d' O# j/ i. e0 K EXAMPLE:. r* C( d" X4 ]; N2 W
  VideoDeCoder.DEF 文件内容如下
1 \9 Z. E0 {: O2 v                                                                 
: R* M0 P1 _* D6 e4 ^/ Q' {        Dump of file VideoDeCoder.dll                                 
" J( L3 X6 E+ h( o+ [3 d4 K, C9 w                                                                       2 `$ s! ]9 I- a# A
        File Type: DLL                                                 3 X9 ^8 Y  C1 Z5 @) c9 @
                                                                       
: k! C, L* {0 R; ~4 H" w" C; {3 E0 m          Section contains the following exports for VideoDeCoder.dll  ; M% K: D  A+ k( s4 X
                                                                       
" ]0 j0 G0 Q. C, b' U) u                   0 characteristics                                   6 k; X( G% i% I2 K7 ?
            3D49E48F time date stamp Fri Aug 02 09:46:55 2002          / f! I0 ~% ^2 X: [
                0.00 version                                          
; P6 y' t3 h0 w. ?: U' `                   1 ordinal base                                      4 _: T+ {, c$ S+ a
                  11 number of functions                              
5 s, r- k! ?1 }1 O                  11 number of names                                   
+ T2 Y  a% x" u5 `                                                                       , q1 N: s1 \1 q% b- w
            ordinal hint RVA      name                                 
) C/ ?3 F6 @* o2 [+ J; c, |0 C                                                                       
/ K$ R& D# g4 E                  1    0 00010F60 _TM_ClearDecoderBuff@4               8 \9 J" t8 L" Q7 R" A
                  2    1 00010E80 _TM_CloseDecoder@4                  
2 f- a, _" b% u; o: }7 P# p                  3    2 00010F00 _TM_DecodePicture@4                  + E+ \) f8 U) H# [
                  4    3 00010ED0 _TM_DecodePictureHeader@4            
9 ~: f* \; `6 k5 H  x' J0 J; I                  5    4 00010FD0 _TM_GetFileEnd@4                     
0 K% x0 y# P$ q. w                  6    5 00011030 _TM_GetUValue@4                      % r: C5 m" h1 c0 e8 y6 f
                  7    6 00011060 _TM_GetVValue@4                      ! f- B3 A6 `* _2 R! L
                  8    7 00011000 _TM_GetYValue@4                      ) S3 v7 w7 s9 x  k) h
                  9    8 00010E10 _TM_OpenDecoder@8                    
" l. P5 f. M2 N  S. a                 10    9 00010F30 _TM_ReturnType@4                     1 [0 S& S6 @) ?" i0 e
                 11    A 00010F90 _TM_SetFileEnd@8                     2 k! r& b3 a, f# V# p
                                                                       & q" d- u% f7 Y3 {
          Summary                                                      # C  w4 R4 }, p
                                                                       2 k# L1 p+ W( F5 P1 o
                2000 .data                                             . V$ a3 @9 R% _
                1000 .rdata                                            # `. l: U- O2 f4 D
                1000 .reloc                                            
' F6 K$ V- Y. {  A9 M8 J               15000 .text                                             : t+ N- c) J3 ]6 b' r6 }/ ]2 ?
  按照以下方法整理:! P* `7 k3 J4 i, a. r4 v
  1>添加LIB说明
& w. j8 k/ X  Y& ~  R8 D   LIBRARY "VideoDeCoder"            ;"xx"为DLL名称
8 b# g* ~( |- \            DESCRIPTION "VideoDeCoder library"  ; Z# Z* [6 C0 b& i' N/ @
        2>去掉导出函数说明端以外的内容,在LIB说明下添加 "EXPROTS" 说明导出函数
& n8 h( i# B1 w  w' i         LIBRARY "VideoDeCoder"
' N5 @( i7 a- F) u   DESCRIPTION "VideoDeCoder library"
) H* g8 T9 }9 K8 u5 ~/ ]2 @6 ~   EXPORTS- d8 ~0 `( j: y6 T  H. _+ U8 ~
            ordinal hint RVA      name                          8 q+ N' D- g8 t* f, e3 d3 `7 T+ [
                                                                & |! p- c3 h4 S# p" t
                  1    0 00010F60 _TM_ClearDecoderBuff@4            
2 p9 X. h0 P% R. S+ J2 h  O                  2    1 00010E80 _TM_CloseDecoder@4            
3 b# C* ]% d+ R) M2 f& N                  3    2 00010F00 _TM_DecodePicture@            
, F. X1 ?. S1 @5 T7 v0 f                  4    3 00010ED0 _TM_DecodePictureH            1 Z/ J: B8 c+ r- [5 k0 k$ |
                  5    4 00010FD0 _TM_GetFileEnd@4              : o  I, h4 v2 E1 h' ?
                  6    5 00011030 _TM_GetUValue@4               
6 P+ U( z+ a* q& r% i- J+ i                  7    6 00011060 _TM_GetVValue@4               $ s% }0 Y% s9 K% H% G- e
                  8    7 00011000 _TM_GetYValue@4               
! k! w; ?8 y7 ~- x1 S! u, R3 M                  9    8 00010E10 _TM_OpenDecoder@8            
! {- }; l/ L/ z9 U) A) Q                 10    9 00010F30 _TM_ReturnType@4              
7 S/ b3 Z: }  L' ]2 m% L                 11    A 00010F90 _TM_SetFileEnd@8     
6 s4 R- p- x. }        3>将所有的函数放至行首,去掉 "hint" 和 "RVA" 数据,留下函数的序号 "ordinal" ,在序号前加上 "@" 符号
9 R: @5 x4 s1 ?* D- j8 A! X        形成 "_导出函数名@参数字节和 @序号" 此种格式(__stdcall 方式调用导出的函数符号是 "函数名称@参数字节和").
" L' Y& ?3 W. b. j2 y6 r( t; C        最后形成.DEF文件如下:
  d% L) @1 l) Y: T- t( V3 V6 V3 l        LIBRARY "VideoDeCoder"
$ A( n2 h" i# t* d$ h' V  DESCRIPTION "VideoDeCoder library"4 A0 q9 @6 R0 ?+ b* U) i' {4 x% n1 P
  EXPORTS
8 k/ c0 v1 o* N- l4 o      
0 s' {) m9 @3 u& ]  TM_ClearDecoderBuff@4             @1    1 V7 L- |0 }! S7 ?% q6 b# I( F
  TM_CloseDecoder@4                 @2    1 f2 n; N( G- d, B( H
  TM_DecodePicture@4                @3   
5 H! q5 I5 x; g" b  TM_DecodePictureHeader@4          @4    8 O, E" |  F$ Y' T- R
  TM_GetFileEnd@4                   @5    7 H9 g7 G1 B* J( l" O, i
  TM_GetUValue@4                    @6   
; a6 c6 X  `0 @, `2 K$ m1 y! C3 k  TM_GetVValue@4                    @7   
/ y" _: J/ d2 `, r" [2 w  TM_GetYValue@4                    @8    ! u7 X' I+ x% n! k, ?
  TM_OpenDecoder@8                  @9   
! a$ u6 C( b2 j- {* I! F  TM_ReturnType@4                  @10   
) J8 s- K& d/ ]  B8 Y  TM_SetFileEnd@8                  @11   
8 T8 d6 _' i  }# Y. p3. 使用VC++的LIB工具,带/DEF:(.def文件名) /MACHINE:IX86(80X86机器),就输出符合VC++格式的的LIB文件了." s! C, ^8 {7 p
EXAMPLE:- f! H- A2 _% X; |0 h0 K* j: v
  LIB /DEF:VideoDeCoder.def /MACHINE:IX867 \: ?( V& [6 S$ [7 c
4. 接时带上LIB文件链接;注意的是当有些动态库DUMPBIN的只有函数名,无"@nn"的参数格式,如C++Builder写的DLL,输出就只有函数名符号,链接时就会报错:
4 P; Y7 b/ F* [% f; X- ] error LNK2002:unresolved external symbol "functionname@nn"
8 \7 X) y- A; S6 ?提示程序中引入的函数符号无法识别,这时只要将DEF文件中相应的函数名称改为functionname@nn方式,重新建立
* j+ o6 ^+ o0 U, `/ w4 GLIB,重新链接即可.2 v! G3 g0 n$ n

6 `) O5 t5 Q4 k* E6 K% N这样就制作成功了符合VC调用方式的LIB了!
  y8 s' i8 Y6 A/ G: K参考:MSDN2000# K; a& E$ O7 \  q" t
要值得一说的是!BORLAND C++BUILDER有一个很好的工具IMPDEF可以直接将DLL中的函数输出到.DEF文件中,只要做一点点修改就可以成为符合VC的DEF文件!1 ^$ ~! \# j4 g( z) M' q, e
IMPDEF xxx.def xxx.dll' I/ j7 I7 ^+ M7 y' b6 a0 P9 h
这种方法只能应用于输出为C格式的__stdcall调用方式经过我的论证有些错误!我利用Borland C++和VC++做论证,发现:
/ V& K! p5 V, c& E9 w; Y  ~而在C++BUILDER中!+ @6 e* P; y; w) H3 P
__cdecl的函数输出前会带一"_"; K: \; o! J# \
__stdcall无特征,只输出函数名. Q( V4 u* }/ r3 w8 H1 x" J6 `
__fastcall函数输出前带一"@"
2 |  j: C# ^, o7 V都无"@nn"后缀格式!
$ x# m! S* f4 a% K  B在VC中!
8 u8 v; g6 T8 s, |. y__cdecl无特征,只输出函数名
; b) O' ?2 `7 ^__stdcall的函数输出前会带一"_"后缀带"@nn"0 i: I4 S& m* k5 k3 w
__fastcall函数输出前带一"@"后缀带"@nn# B) R$ D6 E6 \# {0 p- ^
只要将BC的DEF文件中函数申明格式转换为VC识别的格式就可以利用LIB工具生成LIB;要使用C分格输出(extern "C")才是必须的!而且别忘了在DEF文件中的函数申明不要带“_”啊!:)不然会出现error LNK2001的链接错误!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 11:47 , Processed in 0.020166 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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