如若转载,请尊重个人劳动,务必注明原始出处。iihero 2008-9-28于CSDN
前几天,偶然从论坛里看到帖子,有人问:
手头只有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的最新特性来生成),上述方法,依然是一个补救措施。
分享到:
相关推荐
DLL(Dynamic Link Library)是Windows操作系统中的一个重要组成部分,它是一种可执行文件格式,允许多个程序共享同一块内存空间,从而节省系统资源并提高程序的运行效率。本篇将深入探讨DLL编程指南及其示例程序。 ...
4. 编译和链接:编译源代码并链接生成DLL文件,同时生成对应的.lib文件(导入库)供客户端程序使用。 5. 调用DLL:在客户端程序中,通过LoadLibrary和GetProcAddress函数动态加载和调用DLL中的函数。 静态库(.lib...
17. **快速创建新项目**:使用Custom AppWizard,选择An existing Project,导入现有项目的.dsp文件,完成新项目的生成,可以方便地创建一个与现有项目结构相同但名称可自定义的新项目。 以上是VC6.0的一些实用小...
同时,还会生成一个.lib文件,它是导入库,用于告诉其他项目如何链接到DLL。 6. **测试**:为了验证DLL的功能,通常会创建一个单独的测试项目,即本案例中的“test project”。这个项目将调用DLL中的函数,进行各种...
16. **手工编译资源成DLL**:通过`Rc.exe /v data.rc`、`Cvtres.exe /machine:ix86 data.res`和`Link /SUBSYSTEM:WINDOWS /DLL /NOENTRY data.res`命令,可以生成最小的DLL文件。 17. **快速复制项目**:利用File...
动态链接库(DLL)是Windows操作系统中的一个重要概念,它是一种可执行文件格式,包含可供其他程序使用的函数和数据。在“DLL.rar_动态调用”这个压缩包中,你将找到27个关于Visual C++调用动态链接库的实例,这些都...
静态链接库(Static Link Library,简称.lib文件)是将库中的函数和数据静态地合并到生成的.exe文件中,而DLL则是在程序运行时按需加载,使得程序体积更小,同时允许在不重新编译应用程序的情况下更新库函数。...
因此,能够准确判断一个文件是否已经存在于IE的缓存中对于开发人员来说非常重要。 ### 知识点二:Windows API函数GetUrlCacheEntryInfo的作用与用法 #### 函数介绍 `GetUrlCacheEntryInfo` 是一个Windows API函数...
这种方式生成的DLL文件通常比使用其他方法创建的DLL更小。 #### 16. 快速生成与现有项目完全相同的新项目 如果需要生成一个与现有项目除项目名外完全相同的新项目,可以使用自定义应用程序向导: 1. 选择`File`...
从给定的文件信息中,我们可以提炼出一系列关于C++编程和Visual C++开发环境的知识点,涵盖了开发工具的使用、调试技巧、编译选项、宏定义、代码管理以及常见问题解决方法。以下是对这些知识点的详细阐述: ### 1. ...
3. **编译动态库**:使用Qt Creator或命令行工具,配置项目为动态库(通常选择Win32/Win64动态库),编译生成libdemo.dll和对应的.lib文件。 4. **使用动态库**:在主程序中引用QLibrary,按照上述示例加载和使用...
16. **手动编译纯资源为DLL**:通过Rc.exe、Cvtres.exe和Link命令分别完成资源编译、资源转换和DLL链接,这种方式生成的DLL文件较小。 此外,了解项目文件的作用也是很重要的。.dsp文件存储项目参数配置,是必须...
VC Studio 是一款强大的集成开发环境,尤其对于C++开发者来说,掌握其使用技巧能显著提高编程效率。以下是一些实用的技巧: 1. **括号匹配**:通过快捷键“Ctrl+]”可以快速检查括号匹配情况。如果匹配正确,光标...
接下来,我们需要创建一个`.DEF`文件来描述这个DLL的基本信息和对外导出的函数列表。 ```plaintext LIBRARY example DESCRIPTION 'example.DLL' EXETYPE WINDOWS CODEPRELOAD MOVEABLE DISCARDABLE DATAPRELOAD ...
在visual c++下,每编写一个简单的小程序,就得生成一大串中间文件,另人十分的不爽。下面提供一个新的编写c/c++程序的方法: (1),下载utraledit-32编辑器,推荐v11. (2),在utraledit-32中,分别点击菜单:高级...
首先,开发者需要使用特定的语法在 `.thrift` 文件中定义服务接口和数据结构,之后通过 Thrift 编译器生成对应的客户端和服务端代码。这种方式不仅提高了开发效率,还确保了不同语言间的无缝通信。 #### 二、Thrift...
要在非MFC程序中使用ClassWizard,可以在工程目录下创建一个空的 `.RC` 文件并将其加入工程中。这样就可以激活ClassWizard的功能了。 #### 6. 设置断点 - 按 `F9` 在当前光标处添加或删除断点。 - 或者按 `Ctrl + B...
在Windows操作系统中,当应用程序因各种原因导致崩溃时,系统会生成一个名为“崩溃报告”的文件,用于记录程序异常终止的详细信息。本问题聚焦于一个名为“CrashReport:windows应用程序崩溃报告lib和exe”的主题,这...