Why do I get link errors when the symbol is clearl

2019-08-07 04:41发布

问题:

I've decided to start using ICU in my project, but sadly VS2015 is officially unsupported (i.e. the developers list the incompatibility as a known issue). Luckily someone was kind enough to fix the problems on their own and share the binaries with the world: http://www.npcglib.org/~stathis/blog/precompiled-icu/ . I've downloaded the ICU 56 VS15 package and I'm trying to compile the following simple program:

#include <iostream>

#include <unicode\unistr.h>

int main()
{
    auto myStr = icu::UnicodeString::fromUTF8(u8"кошка");
    std::cout << "length: " << myStr.length() << std::endl;

    std::getchar();
    return 0;
}

When I use the compile time import .lib libraries, everything works fine, but of course I need the DLL libraries at runtime. When I compile against the static ones, sicuxxx.lib, I get link errors for some reason (there are six similar ones, omitted for brevity):

Error   LNK2001 unresolved external symbol "__declspec(dllimport) private: int __thiscall icu_56::UnicodeString::getShortLength(void)const " (__imp_?getShortLength@UnicodeString@icu_56@@ABEHXZ)

I did dumpbin /symbols sicuuc.lib, and in the output I can see the following:

0E8 00000000 SECT47 notype ()    External     | ?getShortLength@UnicodeString@icu_56@@ABEHXZ (private: int __thiscall icu_56::UnicodeString::getShortLength(void)const )

My linker input is as follows: kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;sicudt.lib;sicuin.lib;sicuio.lib;sicule.lib;siculx.lib;sicutest.lib;sicutu.lib;sicuuc.lib;. All the files can clearly be opened by the linker because no "cannot open file" error appears.

Since the symbol is clearly present in the library as shown by dumpbin, why does lib.exe have problems finding it?

回答1:

You need to define U_STATIC_IMPLEMENTATION when compiling your code so that the ICU functions are not marked as imports.

(You can see that the function it is currently trying to find is marked as __declspec(dllimport), which doesn't match the one in the static library.)



回答2:

I would suggest to try to change the mode of linking of runtime in your project (either statically or dynamically). You will find this setting in Settings -> C/C++ -> Code Generation -> Runtime Library (change from either /MT -> /MD or vice versa) . Hope this helps.