zlib在windows上的编译
2013-01-31 17:38:29| 分类: 编程资料 | 标签: |举报 |字号大中小 订阅
因为要进行zip方面的开发,因此需要对于zlib库进行研究,需要编译一个库来使用,同时可以跟踪zlib代码实现,发现问题。
首先从http://www.zlib.net/下载了最新的源代码,版本是1.2.7
解压后,实际已经提供了在VC下编译的工程,目录为:
zlib-1.2.7\contrib\vstudio
其中只有vc9和vc10
因为我用的是vs2008,因此用vc9,打开项目后,其中的zlibstat是编译为静态库
zlibvc是编译为动态库,还有其它一些工程暂时未研究
编译动态库时碰到的第一个问题就是需要link两个文件,
…\masmx86\match686.obj
…\masmx86\inffas32.obj
这个两个文件如何编译呢?
只需要在命令行下设置好vc的编译环境后,执行bld_ml32.bat批处理即可生成需要的文件
如下图:
zlib在windows上的编译 - xzhoumin - MMZHOU的博客
编译生成的库为
ZlibStatDebug\zlibstat.lib
和
ZlibStatRelease\zlibstat.lib
写了一个例子想测试一下,结果出现链接错误:
1>unzip.obj : error LNK2019: 无法解析的外部符号_inflateInit2_,该符号在函数_unzOpenCurrentFile3 中被引用
1>unzip.obj : error LNK2019: 无法解析的外部符号_inflate,该符号在函数_unzReadCurrentFile 中被引用
1>unzip.obj : error LNK2019: 无法解析的外部符号_crc32,该符号在函数_unzReadCurrentFile 中被引用
1>zip.obj : error LNK2001: 无法解析的外部符号_crc32
1>unzip.obj : error LNK2019: 无法解析的外部符号_inflateEnd,该符号在函数_unzCloseCurrentFile 中被引用
1>zip.obj : error LNK2019: 无法解析的外部符号_get_crc_table,该符号在函数_zipOpenNewFileInZip4_64 中被引用
1>zip.obj : error LNK2019: 无法解析的外部符号_deflateInit2_,该符号在函数_zipOpenNewFileInZip4_64 中被引用
1>zip.obj : error LNK2019: 无法解析的外部符号_deflate,该符号在函数_zipWriteInFileInZip 中被引用
1>zip.obj : error LNK2019: 无法解析的外部符号_deflateEnd,该符号在函数_zipCloseFileInZipRaw64 中被引用
1>C:\test\testzlib\Debug\testzlib.exe : fatal error LNK1120: 8 个无法解析的外部命令
刚开始百思不得其解,后来用lib命令查看zlibstat.lib的符号,发现其中的函数名称会多一个@,比如
_get_crc_table在lib输出的符号中为_get_crc_table@0
这个肯定是问题所在,在网上看到如下资料:
(http://blog.csdn.net/shifters/article/details/7163844)
C语言通过不同的调用协议来产生修饰名称,当使用__cdecl(C调用协议)时,会在函数名称前加一个下划线,不考虑参数和返回值。使用__fastcall函数,在函数名称前后各加一@符号,后跟参数长度,不考虑返回值。例如extern “C” int __fastcall Test(int n)的修饰名称为@Test@4. 对于使用标准调用协议(__stdcall)的函数,在函数名称前加一下划线,后跟参数长度,不考虑返回值。如extern “C” int __stdcall Test (int n, int m) 的修饰名称为_Test@8
因此再回到zibstat的工程中
发现函数的定义中有ZEXPORT:
比如(zlib.h):
ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
而ZEXPORT的定义为(zconf.h):
define ZEXPORT WINAPI
而WINAPI的定义为(windef.h)
#define WINAPI __stdcall
因此生成的符号当然有个@加上参数长度了
找到问题后就好解决了,修改函数中ZEXPORT为ZEXPORTVA
#define ZEXPORTVA WINAPIV----->#define WINAPIV __cdecl
注意需要修改头文件和源代码。
另外
1、发现zlibvc.def文件在静态库中是不起作用的,只对动态库的输出符号有作用,这导致走了一点弯路
2、输出符号的方式,在/contrib/vstudio/vc9/x86/ZlibStatDebug下调用
“c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat”
创建编译环境,然后调用>dumpbin /symbols zlibstat.lib >t1.txt
即可在t1.txt文件中看到符号了。
提供一个网络盘下载zlib1.2.7:
下载: zlib-1.2.7.tar.gz
标签:obj,函数,符号,windows,zlib,----,编译,error From: https://blog.csdn.net/XZHOUMIN/article/details/143264787