3
votes

My program (VS 2010) uses Google Buffer Protocol compiled with HAVE_ZLIB option enabled. I compiled the latest version of zlib and added .lib in my project, but during linking i still got

1>libprotobuf.lib(gzip_stream.obj) : error LNK2001: unresolved external symbol _inflateEnd 1>libprotobuf.lib(gzip_stream.obj) : error LNK2001: unresolved external symbol inflateInit2 1>libprotobuf.lib(gzip_stream.obj) : error LNK2001: unresolved external symbol _inflate 1>libprotobuf.lib(gzip_stream.obj) : error LNK2001: unresolved external symbol deflateInit2 1>libprotobuf.lib(gzip_stream.obj) : error LNK2001: unresolved external symbol _deflate 1>libprotobuf.lib(gzip_stream.obj) : error LNK2001: unresolved external symbol _deflateEnd

I used dumpbin.exe /all zlib.lib, it says:

File Type: LIBRARY

....

245 public symbols

....

 4DBE __imp__inflateInit2_@16
 4DBE _inflateInit2_@16

also there are other unresolved symbols in this list.

What's wrong then? Why does the linker can't find these functions?

upd: after recompiling zlib now it's __imp__inflateInit2_@4

1
You seem to have set up __stdcall as the default calling convention when building zlib (perhaps with /Gz compiler switch), while the calling code expects good old __cdecl.Igor Tandetnik
@Igor Tandetnik: just checked the settings, it's __cdecl there, no /Gz option in the command line argumentsfogbit
dumpbin says otherwise. @16 is the tell-tale sign of stdcall name mangling. Another thing to check: perhaps the functions are declared something like void ZLIBAPI inflateEnd(...), and the macro ZLIBAPI ends up expanding to __stdcall in one place but to __cdecl in another.Igor Tandetnik
@IgorTandetnik: from what i got looking at the code, it compiles as __cdecl. Ш recompiled it and now dumpbin.exe says _inflateEnd@4, not @16fogbit
You were looking at inflateInit2 before, not inflateEnd. The number after @ sign is the total number of bytes required for all function parameters, so naturally it may be different for different functions. Again, that's how __stdcall name decoration works (see "Name decoration" section of this document)Igor Tandetnik

1 Answers

2
votes

zlib functions are defined as ZEXPORT. if ZLIB_WINAPI is defined, then ZEXPORT is defined as __stdcall, else it has no value and all zlib function are defined by default to __cdecl.

When i compiled zlib in VS2015, ZLIB_WINAPI was defined in zlib project, and in my c++ project ZLIB_WINAPI was not defined. so my project is looking for __cdecl functions in the zlib .lib file, and the zlib .lib file is compiled as __stdcall.

to fix that, you need to tell the compiler in your project that the zlib .lib file uses __stdcall call convention.

do is by using:

#define ZLIB_WINAPI

before

#include "....\zlib.h"

in your project