现在的位置: 首页 > 综合 > 正文

从dll导出lib

2013年09月19日 ⁄ 综合 ⁄ 共 13553字 ⁄ 字号 评论关闭

如何通过dll文件生成对应的lib文件(开发人员的一个小技巧) 
如若转载,请尊重个人劳动,务必注明原始出处。iihero 2008-9-28于CSDN

转载自:http://blog.csdn.net/iihero/archive/2008/09/28/2990946.aspx

 

前几天,偶然从论坛里看到帖子,有人问:

手头只有oci.dll文件,似乎对应的头文件也有。但是就是找不到对应的lib文件。想让人家邮件发给他一个。

我回忆了一下,好像微软的VC开发工具包里头,有命令可以直接生成对应的lib文件,这样,对于开发人员来说,只要有相应版本的dll文件和头文件,无须对应的lib文件,一样可以隐式加载dll,生成可以执行程序。

 

其实,现在,想链接某dll,无非两种方式:

1. 编译时通过导入库,进而链接dll,Unix下则通过-l链接指令链接具体的动态库,windows下通过

   link  /MAP /SUBSYSTEM:CONSOLE /out:<file>.exe  *.obj <abc>.lib 来链接

2. 在程序里显式的加载动态库,dlopen/LoadLibrary的API调用可以实现此任务,这时是不需要lib文件的。

 

当然,对于Unix/Linux平台而言,静态库动态库,都是通过-l指令来编译完成的。只是运行期,如果是动态库,则需要对应的.so,如果是静态库,不需要对应的.a静态库文件。

 

下面,我就介绍:已知dll文件,如何得到我们第一种方式要用到的导入库lib文件?

这里以PostgreSQL数据库的libpq为例,在%PGHOME%/bin下边有一个动态库文件libpq.dll,它是PostgreSQL客户端要用到的唯一的一个库文件。利用VC带的工具depends,我们看到它里边导出了很多API函数,如下图:

 

 

好,我们下边先进入Visual Studio .net 2003 command prompt,这个在你安装的VS的菜单或者对应的目录里边,一般都是一个批处理器文件:VSVars**.bat之类的,我这里就用VC6来演示,效果是一样的:

 

Microsoft Windows XP [版本 5.1.2600]
(C) 版权所有 1985-2001 Microsoft Corp.

D:/msdev/VC98/Bin>cp d:/pgsql8.3.3/bin/libpq.dll f:/t/

D:/msdev/VC98/Bin>cd /d f:/t/

F:/t>dumpbin /EXPORTS libpq.dll > libpq.txt

F:/t>more libpq.txt
Microsoft (R) COFF Binary File Dumper Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Dump of file libpq.dll

File Type: DLL

  Section contains the following exports for LIBPQ.dll

           0 characteristics
    484CFEC1 time date stamp Mon Jun 09 17:58:25 2008
        0.00 version
           1 ordinal base
         140 number of functions
         140 number of names

    ordinal hint RVA      name

         17    0 000011FE PQbackendPID
         36    1 000011DB PQbinaryTuples
        122    2 0000111D PQcancel
         48    3 00001325 PQclear
         72    4 000011C2 PQclientEncoding

F:/t>

 

我们要注意的一个重要的参数列ordinal列是表示右边的API在dll中的相对序号,这个在后边的def文件里头很重要。

然后使用UltraEdit等带列模式的编辑器,编辑libpq.txt,编辑成文件libpq.def,格式如下:

 

EXPORTS
PQbackendPID                     @          17
PQbinaryTuples                   @          36
PQcancel                         @         122
PQclear                          @          48
PQclientEncoding                 @          72
PQcmdStatus                      @          42
PQcmdTuples                      @          44
PQconndefaults                   @           3
PQconnectPoll                    @          79
PQconnectStart                   @          80
PQconnectdb                      @           1
PQconnectionNeedsPassword        @         140
PQconnectionUsedPassword         @         138
PQconninfoFree                   @          78
PQconsumeInput                   @          26
PQdb                             @           7
PQdescribePortal                 @         134
PQdescribePrepared               @         133
PQdisplayTuples                  @          51
PQdsplen                         @         112
PQencryptPassword                @         128
PQendcopy                        @          31
PQenv2encoding                   @          73
PQerrorMessage                   @          15
PQescapeBytea                    @          89
PQescapeByteaConn                @         127
PQescapeString                   @          88
PQescapeStringConn               @         126
PQexec                           @          21
PQexecParams                     @         101
PQexecPrepared                   @         110
PQfformat                        @         109
PQfinish                         @           4
PQflush                          @          81
PQfmod                           @          41
PQfn                             @          32
PQfname                          @          37
PQfnumber                        @          38
PQfreeCancel                     @         121
PQfreeNotify                     @          87
PQfreemem                        @          95
PQfsize                          @          40
PQftable                         @         107
PQftablecol                      @         108
PQftype                          @          39
PQgetCancel                      @         120
PQgetCopyData                    @         105
PQgetResult                      @          24
PQgetisnull                      @          47
PQgetlength                      @          46
PQgetline                        @          27
PQgetlineAsync                   @          29
PQgetssl                         @         114
PQgetvalue                       @          45
PQhost                           @          10
PQinitSSL                        @         124
PQisBusy                         @          25
PQisnonblocking                  @          82
PQisthreadsafe                   @         129
PQmakeEmptyPGresult              @          49
PQmblen                          @          64
PQnfields                        @          35
PQnotifies                       @          22
PQnparams                        @         131
PQntuples                        @          34
PQoidStatus                      @          43
PQoidValue                       @          71
PQoptions                        @          13
PQparameterStatus                @          97
PQparamtype                      @         132
PQpass                           @           9
PQport                           @          11
PQprepare                        @         118
PQprint                          @          50
PQprintTuples                    @          52
PQprotocolVersion                @          98
PQputCopyData                    @         103
PQputCopyEnd                     @         104
PQputline                        @          28
PQputnbytes                      @          30
PQregisterThreadLock             @         125
PQrequestCancel                  @           6
PQresStatus                      @          66
PQreset                          @           5
PQresetPoll                      @          83
PQresetStart                     @          84
PQresultErrorField               @         106
PQresultErrorMessage             @          65
PQresultStatus                   @          33
PQsendDescribePortal             @         136
PQsendDescribePrepared           @         135
PQsendPrepare                    @         119
PQsendQuery                      @          23
PQsendQueryParams                @         102
PQsendQueryPrepared              @         111
PQserverVersion                  @         113
PQsetClientEncoding              @          85
PQsetErrorVerbosity              @          99
PQsetNoticeProcessor             @          20
PQsetNoticeReceiver              @         100
PQsetdbLogin                     @           2
PQsetnonblocking                 @          86
PQsocket                         @          16
PQstatus                         @          14
PQtrace                          @          18
PQtransactionStatus              @          96
PQtty                            @          12
PQunescapeBytea                  @          94
PQuntrace                        @          19
PQuser                           @           8
appendBinaryPQExpBuffer          @          74
appendPQExpBuffer                @          91
appendPQExpBufferChar            @          68
appendPQExpBufferStr             @          75
createPQExpBuffer                @          77
destroyPQExpBuffer               @          76
enlargePQExpBuffer               @         130
initPQExpBuffer                  @          69
lo_close                         @          54
lo_creat                         @          58
lo_create                        @         123
lo_export                        @          62
lo_import                        @          61
lo_lseek                         @          57
lo_open                          @          53
lo_read                          @          55
lo_tell                          @          59
lo_truncate                      @         137
lo_unlink                        @          60
lo_write                         @          56
pg_char_to_encoding              @         115
pg_encoding_to_char              @          92
pg_utf_mblen                     @          93
pg_valid_server_encoding         @         116
pg_valid_server_encoding_id      @         139
pgresStatus                      @          63
pqsignal                         @         117
printfPQExpBuffer                @          90
resetPQExpBuffer                 @          70
termPQExpBuffer                  @          67

接着使用lib命令即可生成对应的导入库及导出文件libpq.lib和libpq.exp,libpq.lib文件你终于可以得到了。

F:/t>lib /def:libpq.def
Microsoft (R) Library Manager Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

LIB : warning LNK4068: /MACHINE not specified; defaulting to IX86
   Creating library libpq.lib and object libpq.exp

F:/t>dir libpq.*
 驱动器 F 中的卷没有标签。
 卷的序列号是 4CDC-CD55

 F:/t 的目录

2008-09-28  10:44             6,868 libpq.def
2008-09-28  10:36           167,936 libpq.dll
2008-09-28  10:46            16,299 libpq.exp
2008-09-28  10:46            28,488 libpq.lib
2008-09-28  10:37             6,268 libpq.txt
               5 个文件        225,859 字节
               0 个目录  1,673,240,576 可用字节

F:/t>

这个文件拿到你的vc6程序当中,直接可以使用。

当然如果是用vc7, vc71, vc8, vc9,那就拿对应命令行环境控制台窗口进去执行上述命令就可以了。

当然,上述方法,一样适用于C++生成的dll。只不过那些导出符号可读性不会那么好了。

 

最后总结一下,感觉,长期以来,我们习惯了使用微软的Visual Studio IDE,对于普通的命令行使用,反而感到有些茫然,这种现象不太正常,其实,应该像在Unix平台下边一样,学会使用基础的编译命令和makefile的手动编写,那样,你完全可以脱离编译器,使用gvim等编辑器,进行开发,这样反而更能加深对编译链接生成可执行码,有一个比较清晰的思路。

 

好像新的vc9里头,dll文件中可以有强链接,即,它能指定自己依赖的dll的全路径,那么有些东西是不是发生变化,还有待进一步验证。但是对于传统的dll(相信工业级软件不至于傻到所有dll全用vc9的最新特性来生成),上述方法,依然是一个补救措施。

 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/iihero/archive/2008/09/28/2990946.aspx

 

 

 

 

从dll导出lib
版权声明

本文为原创作品,请尊重作者的劳动成果。转载必须保持文章完整性,并以超链接形式注明原始作者“tingsking18”和主站点地址,方便其他朋友提问和指正。

转载自:http://blog.csdn.net/tingsking18/archive/2010/03/18/5394466.aspx

一、使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件
EXAMPLE:

DUMPBIN VideoDeCoder.dll /EXPROTS /OUT:VideoDeCoder.def
 二、将导出的.DEF文件整理为一符合.DEF个数的函数导出文件
EXAMPLE:VideoDeCoder.DEF 文件内容如下Dump of file VideoDeCoder.dll                                 
                                                                      
        File Type: DLL                                                
                                                                      
          Section contains the following exports for VideoDeCoder.dll 
                                                                      
                   0 characteristics                                  
            3D49E48F time date stamp Fri Aug 02 09:46:55 2002         
                0.00 version                                          
                   1 ordinal base                                     
                  11 number of functions                              
                  11 number of names                                  
                                                                      
            ordinal hint RVA      name                                
                                                                      
                  1    0 00010F60 _TM_ClearDecoderBuff@4              
                  2    1 00010E80 _TM_CloseDecoder@4                  
                  3    2 00010F00 _TM_DecodePicture@4                 
                  4    3 00010ED0 _TM_DecodePictureHeader@4           
                  5    4 00010FD0 _TM_GetFileEnd@4                    
                  6    5 00011030 _TM_GetUValue@4                     
                  7    6 00011060 _TM_GetVValue@4                     
                  8    7 00011000 _TM_GetYValue@4                     
                  9    8 00010E10 _TM_OpenDecoder@8                   
                 10    9 00010F30 _TM_ReturnType@4                    
                 11    A 00010F90 _TM_SetFileEnd@8                    
                                                                      
          Summary                                                     
                                                                      
                2000 .data                                            
                1000 .rdata                                           
                1000 .reloc                                           
               15000 .text
按照以下方法整理:
1)添加LIB说明 LIBRARY "VideoDeCoder"            ;"xx"为DLL名称
DESCRIPTION "VideoDeCoder library" 
2)去掉导出函数说明端以外的内容,在LIB说明下添加 "EXPROTS" 说明导出函数 LIBRARY "VideoDeCoder"
DESCRIPTION "VideoDeCoder library"

EXPORTS
            ordinal hint RVA      name                         
                                                               
                  1    0 00010F60 _TM_ClearDecoderBuff@4           
                  2    1 00010E80 _TM_CloseDecoder@4           
                  3    2 00010F00 _TM_DecodePicture@           
                  4    3 00010ED0 _TM_DecodePictureH           
                  5    4 00010FD0 _TM_GetFileEnd@4             
                  6    5 00011030 _TM_GetUValue@4              
                  7    6 00011060 _TM_GetVValue@4              
                  8    7 00011000 _TM_GetYValue@4              
                  9    8 00010E10 _TM_OpenDecoder@8            
                 10    9 00010F30 _TM_ReturnType@4             
                 11    A 00010F90 _TM_SetFileEnd@8
3)将所有的函数放至行首,去掉 "hint" 和 "RVA" 数据,留下函数的序号 "ordinal" ,在序号前加上 "@" 符号 形成 "_导出函数名@参数字节和 @序号" 此种格式(__stdcall 方式调用导出的函数符号是 "函数名称@参数字节和"). 最后形成.DEF文件如下: LIBRARY "VideoDeCoder"
  DESCRIPTION "VideoDeCoder library"

  EXPORTS
     
  TM_ClearDecoderBuff@4             @1   
  TM_CloseDecoder@4                 @2   
  TM_DecodePicture@4                @3   
  TM_DecodePictureHeader@4          @4   
  TM_GetFileEnd@4                   @5   
  TM_GetUValue@4                    @6   
  TM_GetVValue@4                    @7   
  TM_GetYValue@4                    @8   
  TM_OpenDecoder@8                  @9   
  TM_ReturnType@4                  @10   
  TM_SetFileEnd@8                  @11
 三、使用VC++的LIB工具,带/DEF:(.def文件名) /MACHINE:IX86(80X86机器),就输出符合VC++格式的的LIB文件了.
EXAMPLE:LIB /DEF:VideoDeCoder.def /MACHINE:IX86
 四、接时带上LIB文件链接;注意的是当有些动态库DUMPBIN的只有函数名,无"@nn"的参数格式,如C++Builder写的DLL,输出就只有函数名符号,链接时就会报错: error LNK2002:unresolved external symbol "functionname@nn" 提示程序中引入的函数符号无法识别,这时只要将DEF文件中相应的函数名称改为functionname@nn方式,重新建立 LIB,重新链接即可.

最后还有一句,要自动生成.h文件好象是不行的.因为dll里没有保存函数原型,需要反汇编并分析代码才知道每个函数的参数情况.

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tingsking18/archive/2010/03/18/5394466.aspx

抱歉!评论已关闭.