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

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

[复制链接]
发表于 2007-12-20 11:00:22 | 显示全部楼层 |阅读模式
请大家注意!这种方法只能应用于输出为C格式的__stdcall调用方式!
% i) |" H' i7 R% h7 p9 h; Q3 |% @% r2 C  b
1. 使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件7 J0 {0 }1 I( K' T- E6 [& X" x: m/ M
EXAMPLE:
/ ?  [6 p; @% v: W' ~5 }  DUMPBIN VideoDeCoder.dll /EXPROTS /OUT:VideoDeCoder.def" O. g4 v" h- o# u3 Q+ b
8 Q4 D; v  P$ Z( W
2. 将导出的.DEF文件整理为一符合.DEF个数的函数导出文件5 P( V& f4 V$ f$ f- G
EXAMPLE:
( L1 g- D; n0 k/ l/ D5 \" _1 n  VideoDeCoder.DEF 文件内容如下; w1 |* O$ p1 ^1 C7 M9 @
                                                                 
- [* k7 @# S% `( G        Dump of file VideoDeCoder.dll                                  ' R+ g$ m/ Y- j1 @5 T
                                                                       3 ^2 T- @. h% h- n& F( ?! f- E7 }
        File Type: DLL                                                
/ N4 I! L7 P! r- Q                                                                       
4 z- W& Q7 X, p& _$ u  Z- b; ?          Section contains the following exports for VideoDeCoder.dll  ) p6 {$ q' e. m/ \  `0 H2 t
                                                                       
( A. e- `0 [7 C: _, O* M. ]                   0 characteristics                                   8 a+ M+ j4 o# E' ~) B8 X
            3D49E48F time date stamp Fri Aug 02 09:46:55 2002          " A* U) d1 n% c
                0.00 version                                           8 r( ]/ S5 @* B/ `  ^  X
                   1 ordinal base                                      
" c, O1 i2 M* M9 J0 ^, j' ^, }                  11 number of functions                              
5 {3 K$ O+ K6 M7 i/ i                  11 number of names                                   
$ _) R: y. j: h                                                                       ( z6 h: a: z8 z, \6 ^$ e- @
            ordinal hint RVA      name                                 ' b( N  K  A! j: S7 ^: T
                                                                       $ b# u! S) X4 V" B! ], {
                  1    0 00010F60 _TM_ClearDecoderBuff@4               0 z) ^: c7 J6 ~2 M4 _) w: t
                  2    1 00010E80 _TM_CloseDecoder@4                  
6 {- X, i" Z1 b7 a0 X0 o7 }# z                  3    2 00010F00 _TM_DecodePicture@4                  ) R' ?. {) R8 k: r# U
                  4    3 00010ED0 _TM_DecodePictureHeader@4            , l. }$ U8 C: x1 F* x6 X! ~5 [
                  5    4 00010FD0 _TM_GetFileEnd@4                     
; v" J; S- k' D2 P1 D                  6    5 00011030 _TM_GetUValue@4                     
; `- M/ i5 h4 S+ G) ^                  7    6 00011060 _TM_GetVValue@4                      + m' a8 F  q7 r5 H) u: H8 D
                  8    7 00011000 _TM_GetYValue@4                     
/ k8 L8 ~: r( n4 ]5 R8 l# C% x                  9    8 00010E10 _TM_OpenDecoder@8                    & s9 r, c9 R, V0 o4 y9 M3 ]3 B6 j/ y3 l
                 10    9 00010F30 _TM_ReturnType@4                     7 H3 D; t, F" r& z1 J" ^
                 11    A 00010F90 _TM_SetFileEnd@8                       {1 p6 M' |$ D
                                                                       ( e" _* n8 ~5 |& }- i
          Summary                                                      
- E3 R/ q7 q4 k                                                                       : ?) h0 i1 _9 z! u& h# V
                2000 .data                                             ; j% x2 i7 j; b, B) L
                1000 .rdata                                            " u& w3 [, y7 L# `5 l" i/ r* q3 h9 S8 ^
                1000 .reloc                                            
0 W8 y5 A7 @9 A& ]; N5 K. R) G( U               15000 .text                                             
, O7 \  N6 V# e  }. {3 w1 u& `  按照以下方法整理:
2 ?- |( n; @% x' @* D+ i2 S  1>添加LIB说明6 g/ h; d& q( e' p" W
   LIBRARY "VideoDeCoder"            ;"xx"为DLL名称  }" v  K" S8 s& @
            DESCRIPTION "VideoDeCoder library"  3 A* [  K1 M3 k
        2>去掉导出函数说明端以外的内容,在LIB说明下添加 "EXPROTS" 说明导出函数
2 D' C4 T$ E/ n         LIBRARY "VideoDeCoder"
; a" U. L. }, J: n   DESCRIPTION "VideoDeCoder library"2 x- T* g* ]& T5 o
   EXPORTS
/ K4 |3 c& Z/ {- O: r$ G! `7 R            ordinal hint RVA      name                          / z' e$ p  b" b( }; m" Y1 [& |1 ]
                                                                ) _# O& t) ?, d6 @1 T+ A' ~% l
                  1    0 00010F60 _TM_ClearDecoderBuff@4            
5 {; R( g! P$ {, l, [  F  h                  2    1 00010E80 _TM_CloseDecoder@4              G9 B* e3 f* c( i' D0 t
                  3    2 00010F00 _TM_DecodePicture@            
; m& E$ l# X0 H7 Z. Z+ D/ i                  4    3 00010ED0 _TM_DecodePictureH            : i- m1 L( H6 U6 C% n" s! I1 e
                  5    4 00010FD0 _TM_GetFileEnd@4              ' y' E; \8 y' o! P! o5 ~$ k
                  6    5 00011030 _TM_GetUValue@4               
# w. q7 w% ?7 X) A5 H                  7    6 00011060 _TM_GetVValue@4               " ]: M6 D: Y! U9 f
                  8    7 00011000 _TM_GetYValue@4               
$ @0 q* D# R+ d9 m' r& S2 c& `1 G                  9    8 00010E10 _TM_OpenDecoder@8             4 v4 T: P$ F# y2 J- y4 E
                 10    9 00010F30 _TM_ReturnType@4              
/ ^3 c3 x! |, J5 C' O9 i3 W                 11    A 00010F90 _TM_SetFileEnd@8     
, N2 m* P1 U8 Q0 B1 l* L        3>将所有的函数放至行首,去掉 "hint" 和 "RVA" 数据,留下函数的序号 "ordinal" ,在序号前加上 "@" 符号4 X" N* V# Z4 N" O1 b
        形成 "_导出函数名@参数字节和 @序号" 此种格式(__stdcall 方式调用导出的函数符号是 "函数名称@参数字节和")., C+ B8 T, k0 }
        最后形成.DEF文件如下:
3 W: K7 d3 P  R8 }, C; A        LIBRARY "VideoDeCoder"
$ F9 y9 V1 w& P. j  DESCRIPTION "VideoDeCoder library"
; J4 U: Y* a) H* t  EXPORTS6 s/ w7 O+ b3 H. U; N& i/ n/ n
      
: H$ q2 _5 `6 \4 z: ?- m6 B7 I  TM_ClearDecoderBuff@4             @1   
8 T7 z: G4 d$ N  TM_CloseDecoder@4                 @2   
/ V7 r8 c$ N$ r, x4 p3 T3 x  ^0 n  TM_DecodePicture@4                @3   
0 f) N( d8 u4 b- U% p  TM_DecodePictureHeader@4          @4    0 r* }$ e3 r) C8 a0 ^4 Q0 Y, s
  TM_GetFileEnd@4                   @5   
* G( i. ]  z7 H5 J. Z6 [  TM_GetUValue@4                    @6    7 ?: h$ i3 M! b6 F8 {- ^
  TM_GetVValue@4                    @7    6 f0 c! w9 }! g5 i$ b: n: K
  TM_GetYValue@4                    @8    6 }, ~. w0 H# A! |
  TM_OpenDecoder@8                  @9    ; Y) b1 p- x  ]7 r( F
  TM_ReturnType@4                  @10   
8 p( N8 P( a, J% O5 |6 T# G  TM_SetFileEnd@8                  @11    " P5 _- n/ j, J8 j' c# \
3. 使用VC++的LIB工具,带/DEF:(.def文件名) /MACHINE:IX86(80X86机器),就输出符合VC++格式的的LIB文件了.
  R) M+ X+ y0 x' P/ o% p" ]& i EXAMPLE:
, i+ m7 b2 C9 p# ^% C  LIB /DEF:VideoDeCoder.def /MACHINE:IX869 R1 K9 U% q+ f: z; \- e
4. 接时带上LIB文件链接;注意的是当有些动态库DUMPBIN的只有函数名,无"@nn"的参数格式,如C++Builder写的DLL,输出就只有函数名符号,链接时就会报错:/ Z! v: H7 P2 ~8 ?( B. U' P3 |
error LNK2002:unresolved external symbol "functionname@nn"
0 g7 B! T4 w# q* Q提示程序中引入的函数符号无法识别,这时只要将DEF文件中相应的函数名称改为functionname@nn方式,重新建立
$ O0 u3 E" ~0 h% ]/ @/ S8 LLIB,重新链接即可.  r# K! s3 t& T

- _; |  L' \/ a, l: n1 _这样就制作成功了符合VC调用方式的LIB了!
" U& z" m% Y. B9 U8 G) m6 N参考:MSDN2000
6 v! s- T: M- ?1 u9 E- [9 R$ |要值得一说的是!BORLAND C++BUILDER有一个很好的工具IMPDEF可以直接将DLL中的函数输出到.DEF文件中,只要做一点点修改就可以成为符合VC的DEF文件!! V1 H0 Y1 S7 Z3 j
IMPDEF xxx.def xxx.dll% q* C; t. _8 A' L5 k
这种方法只能应用于输出为C格式的__stdcall调用方式经过我的论证有些错误!我利用Borland C++和VC++做论证,发现:+ E3 l7 {4 {! f! N5 _, i
而在C++BUILDER中!
* K. y, A. S& {! b& n0 O& O5 Q) E__cdecl的函数输出前会带一"_"; l& I& c2 X; C( }6 I
__stdcall无特征,只输出函数名! L/ Q% {  h0 K: I9 g
__fastcall函数输出前带一"@"
9 F: u( r  {7 E+ J都无"@nn"后缀格式!
1 Q' u8 k, f1 `在VC中!
7 n! I3 T+ b4 g* y  o$ _7 J3 c; r__cdecl无特征,只输出函数名
/ f$ O# v( g3 ~  k4 ^" P__stdcall的函数输出前会带一"_"后缀带"@nn"- B: _1 Z! P# Z& S* H! {
__fastcall函数输出前带一"@"后缀带"@nn
) ?! ^2 E& h1 d7 X) @6 m0 W只要将BC的DEF文件中函数申明格式转换为VC识别的格式就可以利用LIB工具生成LIB;要使用C分格输出(extern "C")才是必须的!而且别忘了在DEF文件中的函数申明不要带“_”啊!:)不然会出现error LNK2001的链接错误!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-9 05:09 , Processed in 0.035608 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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