【发布时间】:2013-09-18 04:37:16
【问题描述】:
我的程序 (VS 2010) 使用启用了HAVE_ZLIB 选项编译的 Google 缓冲区协议。我编译了最新版本的zlib 并在我的项目中添加了.lib,但是在链接过程中我仍然得到了
1>libprotobuf.lib(gzip_stream.obj):错误 LNK2001:未解决 外部符号 _inflateEnd 1>libprotobuf.lib(gzip_stream.obj):错误 LNK2001:未解析的外部符号 inflateInit2 1>libprotobuf.lib(gzip_stream.obj):错误 LNK2001:未解决 外部符号 _inflate 1>libprotobuf.lib(gzip_stream.obj):错误 LNK2001:未解析的外部符号 deflateInit2 1>libprotobuf.lib(gzip_stream.obj):错误 LNK2001:未解决 外部符号 _deflate 1>libprotobuf.lib(gzip_stream.obj):错误 LNK2001:未解析的外部符号 _deflateEnd
我用dumpbin.exe /all zlib.lib,上面写着:
文件类型:图书馆
.... 245 public symbols .... 4DBE __imp__inflateInit2_@16 4DBE _inflateInit2_@16
此列表中还有其他未解析的符号。
那怎么了?为什么链接器找不到这些函数?
upd:重新编译后zlib现在是__imp__inflateInit2_@4
【问题讨论】:
-
在构建 zlib 时,您似乎已将
__stdcall设置为默认调用约定(可能使用/Gz编译器开关),而调用代码需要旧的__cdecl。 -
@Igor Tandetnik:刚刚检查了设置,那里是
__cdecl,命令行参数中没有/Gz选项 -
dumpbin 另有说明。
@16是 stdcall 名称修改的标志。另一件要检查的事情:也许函数被声明为void ZLIBAPI inflateEnd(...),而宏ZLIBAPI最终在一个地方扩展为__stdcall,但在另一个地方扩展为__cdecl。 -
@IgorTandetnik:从我看到的代码来看,它编译为 __cdecl。 Ш 重新编译它,现在dumpbin.exe 说
_inflateEnd@4,而不是@16 -
您之前查看的是
inflateInit2,而不是inflateEnd。 @符号后面的数字是所有函数参数所需的总字节数,所以对于不同的函数自然可能会有所不同。同样,这就是 __stdcall 名称修饰的工作方式(参见 this document 的“名称修饰”部分)
标签: c++ visual-c++ linker zlib unresolved-external