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

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

[复制链接]
发表于 2007-12-20 11:00:22 | 显示全部楼层 |阅读模式
请大家注意!这种方法只能应用于输出为C格式的__stdcall调用方式!
- [2 n/ c+ ~6 `7 V3 f# E9 s3 U: _. i7 p0 J1 o3 O& L" E
1. 使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件+ q+ g+ l  `% |3 V& Y; I% E0 ?
EXAMPLE:  w1 L* B6 x/ Q* y3 R3 S9 R
  DUMPBIN VideoDeCoder.dll /EXPROTS /OUT:VideoDeCoder.def, K) N: p2 W2 B( L/ P  }
! v- m9 a8 L; m) }. s0 L0 V# n) o
2. 将导出的.DEF文件整理为一符合.DEF个数的函数导出文件4 S. w9 V4 V2 X  E1 |. v  \3 m+ z
EXAMPLE:1 O, Y7 U/ m. |
  VideoDeCoder.DEF 文件内容如下5 w& M9 S( d. ?$ l6 W% P
                                                                 ; {' k  j% U7 P! P6 Q
        Dump of file VideoDeCoder.dll                                 
1 \$ Z7 l. f  o                                                                       ) G" K. @" N3 d  U- D+ A3 V8 g
        File Type: DLL                                                
& V/ n! `4 X" x% A' N) m                                                                       
6 M0 o. T" v& e: ]          Section contains the following exports for VideoDeCoder.dll  4 q& {9 \) e4 @' r& n3 K
                                                                       
  B# \% q0 ?3 m; P5 P& E9 \                   0 characteristics                                   8 [3 E9 d/ c: q; m- [8 h. m
            3D49E48F time date stamp Fri Aug 02 09:46:55 2002         
3 N( c0 |0 I" U' X                0.00 version                                          
) \8 O! z5 z: {% Y6 a( C. j- o                   1 ordinal base                                      6 l  p& C" ?6 u8 M
                  11 number of functions                               # \9 `* o2 a5 A% [
                  11 number of names                                   
+ S2 X" P$ Q0 q  O                                                                       2 D. B5 Y; p+ N
            ordinal hint RVA      name                                 
5 `; L' j: |' q9 |                                                                       4 ~$ g$ a( h4 ~4 h. n7 N
                  1    0 00010F60 _TM_ClearDecoderBuff@4               : p" X2 \! g1 g5 P' u: ?
                  2    1 00010E80 _TM_CloseDecoder@4                  
3 F( c. |8 @& l. p                  3    2 00010F00 _TM_DecodePicture@4                  
0 U4 D! G6 @. |7 C$ ^                  4    3 00010ED0 _TM_DecodePictureHeader@4            ' T4 L" E5 P' @3 B$ s
                  5    4 00010FD0 _TM_GetFileEnd@4                     
; f% U+ H4 w# I                  6    5 00011030 _TM_GetUValue@4                     
( E3 n1 M( \/ o$ B                  7    6 00011060 _TM_GetVValue@4                     
. L! O. b$ D7 Q+ V' @* j                  8    7 00011000 _TM_GetYValue@4                     
2 O; |+ d( L( Q  l, D                  9    8 00010E10 _TM_OpenDecoder@8                    
+ Q; a8 e, `) m$ f/ D" \* d8 ]                 10    9 00010F30 _TM_ReturnType@4                     8 V( n- T) P; {3 {  Z. ~
                 11    A 00010F90 _TM_SetFileEnd@8                     2 j) b8 u; j% E! x
                                                                       - u3 Z0 R! ~2 t- V3 Q: W
          Summary                                                      
( l0 v/ y6 ?: T$ `                                                                       
2 ?" z8 D, u8 `4 L                2000 .data                                             
6 i# Y( V$ `8 Z+ o  ~; R# v                1000 .rdata                                            3 e; H& {. d# z) E$ C2 R
                1000 .reloc                                            $ v3 s, L9 X- c7 Z
               15000 .text                                             
) W* w8 C3 j+ k! Y/ y8 ]' a& o9 M  按照以下方法整理:
5 O, \/ v# ]/ t  1>添加LIB说明
; P1 j+ ~, ]- _) E* Y' J   LIBRARY "VideoDeCoder"            ;"xx"为DLL名称3 \+ X- r) O8 @5 ^5 t. D
            DESCRIPTION "VideoDeCoder library"  
' |: n( k6 I$ z5 Y% d) F% ?  a+ T        2>去掉导出函数说明端以外的内容,在LIB说明下添加 "EXPROTS" 说明导出函数
7 O' O* D5 z+ j# m/ X  L$ y         LIBRARY "VideoDeCoder"
5 e3 Y0 p: [4 t0 b( I1 n: Z( q( i   DESCRIPTION "VideoDeCoder library"
& i3 {. k( R1 v  N. W   EXPORTS
- @% i2 C( ]; l0 O% M8 j' Q$ z            ordinal hint RVA      name                          1 P* ]& S/ X! d, A9 ~6 ~7 k
                                                                , K. B7 U' z4 h/ y! z
                  1    0 00010F60 _TM_ClearDecoderBuff@4            
3 Q! m# |# b$ }3 N6 }1 [                  2    1 00010E80 _TM_CloseDecoder@4            - ^& g( S9 f, T' w( x
                  3    2 00010F00 _TM_DecodePicture@            / y3 U5 d1 J4 d) x
                  4    3 00010ED0 _TM_DecodePictureH            
2 Z! e8 C8 ?9 r! M                  5    4 00010FD0 _TM_GetFileEnd@4              % x8 `& w% t  M
                  6    5 00011030 _TM_GetUValue@4               / P% Q" `3 L- n9 L: C
                  7    6 00011060 _TM_GetVValue@4               2 m0 W0 H- \+ O3 n2 X) A# H
                  8    7 00011000 _TM_GetYValue@4               0 _, R: }: K) Q2 y/ H) P, m( S; m) \
                  9    8 00010E10 _TM_OpenDecoder@8             ' F0 K4 m0 D- C! h, z
                 10    9 00010F30 _TM_ReturnType@4              ( }6 C* U9 O' M
                 11    A 00010F90 _TM_SetFileEnd@8     
9 z1 X, v5 N2 }% M  W( W% x' N        3>将所有的函数放至行首,去掉 "hint" 和 "RVA" 数据,留下函数的序号 "ordinal" ,在序号前加上 "@" 符号
  G0 z; V( N5 q# d: U6 ~0 S        形成 "_导出函数名@参数字节和 @序号" 此种格式(__stdcall 方式调用导出的函数符号是 "函数名称@参数字节和").
& ]& r+ {0 S- A7 |8 y        最后形成.DEF文件如下:' Y9 Q8 H/ Q3 l
        LIBRARY "VideoDeCoder"
  f% b, |/ B/ h  L. H8 a  DESCRIPTION "VideoDeCoder library"( C6 r, f/ L2 M3 V  D
  EXPORTS: k) v3 @0 f# ~( }8 l  A: I
      % G- n  I$ v% N( ^  K
  TM_ClearDecoderBuff@4             @1   
$ A. |( T' ^) R5 K6 w$ |4 U+ h/ G  TM_CloseDecoder@4                 @2    / l' y! ?% e; |
  TM_DecodePicture@4                @3   
, [' `1 U! F% w: y# s% x: G  TM_DecodePictureHeader@4          @4    7 e+ T2 H7 F5 s  x! h, i
  TM_GetFileEnd@4                   @5   
, S; s+ D7 v# S# d: W) ^  TM_GetUValue@4                    @6    3 `/ m9 ?8 d" U8 T
  TM_GetVValue@4                    @7    # f# o: a" e/ X% M4 {, P
  TM_GetYValue@4                    @8   
( F3 J. }/ k3 k' X3 P- A$ [& M2 F  TM_OpenDecoder@8                  @9   
* p( W% m& p: t7 F$ u: V, q& K5 m9 q  TM_ReturnType@4                  @10   
: V; ?2 u% K7 g4 h4 S8 Z8 {7 @  TM_SetFileEnd@8                  @11   
) }* r& U" e' B3 S6 g& V3. 使用VC++的LIB工具,带/DEF:(.def文件名) /MACHINE:IX86(80X86机器),就输出符合VC++格式的的LIB文件了./ o' f" F- N" k& a6 l$ b, K# |
EXAMPLE:, W  U* Q7 B/ J
  LIB /DEF:VideoDeCoder.def /MACHINE:IX86* E: D" q0 I% Z$ c; o+ X& ]
4. 接时带上LIB文件链接;注意的是当有些动态库DUMPBIN的只有函数名,无"@nn"的参数格式,如C++Builder写的DLL,输出就只有函数名符号,链接时就会报错:- Y; n1 ]! i7 H# @
error LNK2002:unresolved external symbol "functionname@nn"
& [! g3 m8 p( O0 Y提示程序中引入的函数符号无法识别,这时只要将DEF文件中相应的函数名称改为functionname@nn方式,重新建立. q4 W9 x- a1 {( H
LIB,重新链接即可.
8 p1 \+ ^) Q' I/ l# K: r" ?* b+ c6 W$ u2 u+ e. d
这样就制作成功了符合VC调用方式的LIB了!) x% Y* C2 k$ p/ z1 S7 G# h& a
参考:MSDN2000+ }% }8 G9 n) G4 i4 j% s
要值得一说的是!BORLAND C++BUILDER有一个很好的工具IMPDEF可以直接将DLL中的函数输出到.DEF文件中,只要做一点点修改就可以成为符合VC的DEF文件!; ~! C. Y7 N$ ~
IMPDEF xxx.def xxx.dll0 {$ z& z# B0 r
这种方法只能应用于输出为C格式的__stdcall调用方式经过我的论证有些错误!我利用Borland C++和VC++做论证,发现:
& z$ e+ y1 i( e% F4 r6 n0 q% }0 P$ \而在C++BUILDER中!6 u9 \2 P: @3 `5 [
__cdecl的函数输出前会带一"_"
- L3 R4 W' M* K6 j' `: G# A3 a0 P__stdcall无特征,只输出函数名- F' F- _( N, l2 |: v6 O
__fastcall函数输出前带一"@"
/ l5 \2 J, A2 r3 d1 v1 B都无"@nn"后缀格式!' k. m9 \  b" t2 t
在VC中!
2 q* I: k: }4 E2 W! t__cdecl无特征,只输出函数名
3 q. V& s2 `! }- @1 {__stdcall的函数输出前会带一"_"后缀带"@nn"; b/ ?' g5 p. o4 t$ i9 g3 b
__fastcall函数输出前带一"@"后缀带"@nn
. J; K# q3 Z1 u' b* ~1 M9 j只要将BC的DEF文件中函数申明格式转换为VC识别的格式就可以利用LIB工具生成LIB;要使用C分格输出(extern "C")才是必须的!而且别忘了在DEF文件中的函数申明不要带“_”啊!:)不然会出现error LNK2001的链接错误!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-19 12:40 , Processed in 0.015912 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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