3

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

fogbit
  • 1,961
  • 6
  • 27
  • 41
  • 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 Sep 13 '13 at 13:31
  • @Igor Tandetnik: just checked the settings, it's ``__cdecl`` there, no ``/Gz`` option in the command line arguments – fogbit Sep 13 '13 at 13:34
  • 1
    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 Sep 13 '13 at 13:41
  • @IgorTandetnik: from what i got looking at the code, it compiles as __cdecl. Ш recompiled it and now dumpbin.exe says `_inflateEnd@4`, not `@16` – fogbit Sep 13 '13 at 14:16
  • 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](http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx)) – Igor Tandetnik Sep 13 '13 at 14:34

1 Answers1

2

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

user1438233
  • 1,153
  • 1
  • 14
  • 30
  • 1
    While this answer may be correct, please add some explanation. Imparting the underlying logic is more important than just giving the code, because it helps the OP and other readers fix this and similar issues themselves. – CodeMouse92 Oct 06 '15 at 14:01
  • 2
    @JasonMc92 I added an explanation – user1438233 Oct 06 '15 at 15:19