Unresolved external symbol with ICU - c++

We have code that uses the ICU library for working with Unicode strings. When we try to build it, we get no compile errors, but the link fails. I created a small test program with the following code:
#define U_STATIC_IMPLEMENTATION
#undef INT64_C
#undef UINT64_C
#include <unicode/coll.h>
void icu_test()
{
UErrorCode success = U_ZERO_ERROR;
Collator* myCollator = Collator::createInstance(success);
VERIFY(U_SUCCESS(success));
myCollator->setStrength(Collator::QUATERNARY);
UChar Word1[10] = _T("this");
UChar Word2[10] = _T("that");
// Compare two strings in the default locale
bool result = myCollator->greater(Word1, Word2);
}
This program also fails to link with:
error LNK2019: unresolved external symbol "public: __thiscall
icu_3_2::UnicodeString::UnicodeString(wchar_t const *)"
(??0UnicodeString#icu_3_2##QAE#PB_W#Z) referenced in function "void
__cdecl icu_test(void)" (?icu_test##YAXXZ)
(Is 0UnicodeString the constructor, perhaps?) When I use dumpbin to look at the exported symbols in the ICU libraries, I see the following:
??0UnicodeString#icu_3_2##QAE#ABV01##Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(class icu_3_2::UnicodeString const &))
??0UnicodeString#icu_3_2##QAE#ABV01#H#Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(class icu_3_2::UnicodeString const &,int))
??0UnicodeString#icu_3_2##QAE#ABV01#HH#Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(class icu_3_2::UnicodeString const &,int,int))
??0UnicodeString#icu_3_2##QAE#CPBGH#Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(signed char,unsigned short const *,int))
??0UnicodeString#icu_3_2##QAE#G#Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(unsigned short))
??0UnicodeString#icu_3_2##QAE#H#Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(int))
??0UnicodeString#icu_3_2##QAE#HHH#Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(int,int,int))
??0UnicodeString#icu_3_2##QAE#PAGHH#Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(unsigned short *,int,int))
??0UnicodeString#icu_3_2##QAE#PBD0#Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(char const *,char const *))
??0UnicodeString#icu_3_2##QAE#PBDH0#Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(char const *,int,char const *))
??0UnicodeString#icu_3_2##QAE#PBDHPAUUConverter##AAW4UErrorCode###Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(char const *,int,struct UConverter *,enum UErrorCode &))
??0UnicodeString#icu_3_2##QAE#PBDHW4EInvariant#01##Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(char const *,int,enum icu_3_2::UnicodeString::EInvariant))
??0UnicodeString#icu_3_2##QAE#PBG#Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(unsigned short const *))
??0UnicodeString#icu_3_2##QAE#PBGH#Z (public: __thiscall icu_3_2::UnicodeString::UnicodeString(unsigned short const *,int))
??0UnicodeString#icu_3_2##QAE#XZ (public: __thiscall icu_3_2::UnicodeString::UnicodeString(void))
So none of these quite match the first unresolved external, because of the stuff at the end of the identifier (e.g. ##QAE#PB_W#Z), which does not come from our code. Not sure how this is generated or what to do about it.
I tried downloading the latest version of ICU (60.2), but it only comes in a x64 version, while our program builds for x86.
I made sure that the ICU library folder is included in the link settings.
We also made sure to define U_STATIC_IMPLEMENTATION, as described in this post:
Why do I get link errors when the symbol is clearly present in the static library I link against?
In that post, they were able to locate the relevant symbol in the library, but we cannot.
Can anyone help us understand what is causing this link error?

I tried building a static library of ICU 60.2 but ran into problems and I was unable to get help from ICU support to build it.
I tried downloading pre-built ICU 59.1 libraries from this website. But had a different linker error and no idea what to do with that.
I saw that my code was trying to pass a wchar_t* to icu::greater(), which expects UnicodeString arguments, so I inferred that this is where type conversion causes the UnicodeString to be constructed. I changed the code to do an explicit conversion to UnicodeString and then pass that, but I still got the same linker error.
Finally, my coworker found some information about a potential problem with wchar_t. So that was it - our best understanding is that since our code was originally working with MS Visual C++ 6.0, and it was able to link to ICU 3.2 in that context, it was linking with the old definition of wchar_t, but the new definition of wchar_t was changing the way the name decoration was being generated. Adding -Zc:wchar_t- to the compile options (in VS 2017, go to Project Properties, C/C++ All Options, 'Additional Options' line), caused it to link successfully after a full recompile.
Very subtle.

Related

unresolved external symbol while using wchar_t in managed c++ project

I have one C++ project with settings of Unicode as character set and /clr option for common language run time support. I am calling some function of MFC dll (with setting of MultiByte character set) and I am getting some liking error on those functions which are using wchar_t. Same dll is working file for those unicode c++ projects where /clr option is not set (i.e. no common language run time support). I have done the google and tried some thing like:--
Replace Cstring with std:string but both are giving same error.
Example for std: string:--
error LNK2001: unresolved external symbol "public: __thiscall
CEventLog::CEventLog(wchar_t const *)" (??0CEventLog##QAE#PB_W#Z)
for Cstring:--
error LNK2019: unresolved external symbol "public: bool __thiscall
CIITAdoField::GetValue(class ATL::CStringT > > &)"
(?GetValue#CIITAdoField##QAE_NAAV?$CStringT#_WV?$StrTraitMFC_DLL#_WV?$ChTraitsCRT#_W#ATL#####ATL###Z)
referenced in function "public: bool __thiscall
Iit::DataFeedSvr::SpeedCache::CacheLoader > >,class
Iit::DataFeedSvr::SpeedCache::HolidayScheduleInfo,struct
Iit::DataFeedSvr::SpeedCache::HolidayScheduleSpeedCacheParam>
::Reload(class Iit::DataFeedSvr::SpeedCache::DoubleKeyCacheInstance > >,class
Iit::DataFeedSvr::SpeedCache::HolidayScheduleInfo,struct
Iit::DataFeedSvr::SpeedCache::HolidayScheduleSpeedCacheParam> &,class
CIITAdoRecordset &,enum
Iit::DataFeedSvr::SpeedCache::ERefreshType,class
Iit::DataFeedSvr::SpeedCache::CacheObserver const *)"
(?Reload#?$CacheLoader#V?$DoubleKeyCacheInstance#JV?$CStringT#_WV?$StrTraitMFC_DLL#_WV?$ChTraitsCRT#_W#ATL#####ATL##VHolidayScheduleInfo#SpeedCache#DataFeedSvr#Iit##UHolidayScheduleSpeedCacheParam#456##SpeedCache#DataFeedSvr#Iit###SpeedCache#DataFeedSvr#Iit##QAE_NAAV?$DoubleKeyCacheInstance#JV?$CStringT#_WV?$StrTraitMFC_DLL#_WV?$ChTraitsCRT#_W#ATL#####ATL##VHolidayScheduleInfo#SpeedCache#DataFeedSvr#Iit##UHolidayScheduleSpeedCacheParam#456##234#AAVCIITAdoRecordset##W4ERefreshType#234#PBVCacheObserver#234##Z)
I have checked the setting like "Treat Wchar_t as Built in type" and it is file.
I have tried to explicitly export function and class using __declspec(dllexport) but no luck.
I can not change my project from unicode to multibyte or can not change the setting of /clr option as it starts giving other error.
Please suggest the solution. Thanks in advance.
Do a 'dumpbin' on the external DLL to see what's exported. If your CEventLog::CEventLog is not exporting a char based constructor you won't be able to import it, simple as that.
It doesn't look from your example that the /clr switch is causing the problem. Try creating a brand new Unicode project (without the CLR) just to check you really can link to the external DLL.

I have a third party lib, I have error LNK2019: unresolved external ... How to investigate to fix it

I have a third party libs. (msvc10) a MT/MD (Static cfgs's) and dynamic DLL cfg.
I have qt + msvc10 express + win sdk.7
Ok , I use the existing examples offered, (using the libs) I can't compile ..... I have 4 unresolved external errors of the same lib.
(But I have zero errors for the others)
I have not support for these lib...... (but they are legal, I am a member without rights)
Which are the steps to investigate a possible fix? Where I have to look ?
Thanks.
Edit 1:
The errors was:
TD_ExamplesCommon.lib(ExHostAppServices.obj) : error LNK2019: unresolved external symbol __imp__RegEnumValueW#32 referenced in function "public: virtual bool __thiscall ExHostAppServices::ttfFileNameByDescriptor(class OdTtfDescriptor const &,class OdString &)" (?ttfFileNameByDescriptor#ExHostAppServices##UAE_N ABVOdTtfDescriptor##AAVOdString###Z)
TD_ExamplesCommon.lib(ExHostAppServices.obj) : error LNK2019: unresolved external symbol __imp__RegCloseKey#4 referenced in function "public: virtual bool __thiscall ExHostAppServices::ttfFileNameByDescriptor(class OdTtfDescriptor const &,class OdString &)" (?ttfFileNameByDescriptor#ExHostAppServices##UAE_N ABVOdTtfDescriptor##AAVOdString###Z)
TD_ExamplesCommon.lib(ExHostAppServices.obj) : error LNK2019: unresolved external symbol __imp__RegQueryValueExW#24 referenced in function "public: virtual bool __thiscall ExHostAppServices::ttfFileNameByDescriptor(class OdTtfDescriptor const &,class OdString &)" (?ttfFileNameByDescriptor#ExHostAppServices##UAE_N ABVOdTtfDescriptor##AAVOdString###Z)
TD_ExamplesCommon.lib(ExHostAppServices.obj) : error LNK2019: unresolved external symbol __imp__RegOpenKeyExW#20 referenced in function "public: virtual bool __thiscall ExHostAppServices::ttfFileNameByDescriptor(class OdTtfDescriptor const &,class OdString &)" (?ttfFileNameByDescriptor#ExHostAppServices##UAE_N ABVOdTtfDescriptor##AAVOdString###Z)
..\exe\OdaQtApp.exe : fatal error LNK1120: 13 unresolved externals
During this post I have received a solution: I have to link with Advapi32.lib...
My question is : how can I know this ?
I have tried the dependencyywalker, but it cant use the .lib's....
During this post I have received a solution: I have to link with Advapi32.lib... My question is : how can I know this?
When you get an "unresolved external" error from the linker, that means that it was looking for a match for a function or variable name that some object file needs and the linker was unable to find that name defined in one of the object files or libraries.
Start by looking at the first of these errors (I've reformatted it a bit to make it slightly more readable - I encourage yo to do the same next time you come across one of these):
TD_ExamplesCommon.lib(ExHostAppServices.obj) : error LNK2019: unresolved external symbol
__imp__RegEnumValueW#32 referenced in function
"public: virtual bool __thiscall ExHostAppServices::ttfFileNameByDescriptor(
class OdTtfDescriptor const &,class OdString &)"
(?ttfFileNameByDescriptor#ExHostAppServices##UAE_N ABVOdTtfDescriptor##AAVOdString###Z)
There's a lot of stuff in that error message (much of it may look like garbage). Fortunately, much of it can be ignored in most cases. The most important item is that the linker is looking for the symbol __imp__RegEnumValueW#32 The name has some gunk on it, but fortunately it's pretty recognizable anyway.
the __imp__ prefix indicates it's looking for a DLL import. In nearly all cases that can be ignored for your purposes.
the #32 suffix is something the Microsoft compiler adds to function names for certain calling conventions. It's also generally not important for your purposes (for the record it indicates that the function expects 32 bytes of argument data)
So we're left with the fact that the linker is looking for RegEnumValueW. That looks a lot like the name of a Win32 API.
If you look at the docs for RegEnumValueW (or RegEnumValue, since many Win32 APIs have both an A and a W variant to handle ANSI/UNICODE builds) we'll find in the documentation this bit of information:
Requirements
Minimum supported client Windows 2000 Professional
Minimum supported server Windows 2000 Server
Header Winreg.h (include Windows.h)
>> Library Advapi32.lib
DLL Advapi32.dll
Unicode and ANSI names RegEnumValueW (Unicode) and
RegEnumValueA (ANSI)
That's how you know you need advapi32.lib.
So in the future, when you get an "unresolved external" error from the linker, just ignore most of the gunk in the error message and concentrate on the symbol it says it can't find - that should lead you to the library, object file or other item you might be missing.
Just for the record, advapi32.lib will be needed by most Windows applications of any complexity.
you can try to use dependencywalker to see the list of dependencies for your dlls and see what it's missing.
have you entered the *.lib file in the linker options? (input --> additional dependencies"), and in addition the path to the .lib in libraries directories option?

linking error with CMake and Visual Studio 2010

I'm trying to compile osgearth library with VS2010. The library uses CMake, so after setting all dependencies it generates a VS2010 solution file. However when running build in VS I get this linker error (and 200 similar ones)
Error 7 error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall std::basic_ofstream >::`vbase destructor'(void)" (_imp??_D?$basic_ofstream#DU?$char_traits#D#std###std##QAEXXZ) referenced in function "public: virtual void __thiscall osgEarth::DiskCache::setImage(class osgEarth::TileKey const &,struct osgEarth::CacheSpec const &,class osg::Image const *)" (?setImage#DiskCache#osgEarth##UAEXABVTileKey#2#ABUCacheSpec#2#PBVImage#osg###Z) C:\swproj\osgearth-src\src\osgEarth\Caching.obj osgEarth
I'm not very familiar with C++, is there anything else I have to set up?
You're missing a reference to std::ofstream. You either need an #include in one of your files or a reference to the standard library dll in your project.

Linking error while using Visual Studio 2005(VC8)

I am getting a bunch of linking errors while trying to link the release version of an executable(debug version does not have the same issue). Comparing the command line for the link does not reveal any issues.
there are broadly 2 types of errors neither of which I can get a handle on.
The first kind complains about a unresolved external symbol _declspec(dllimport)
As an example:
error LNK2019: unresolved external symbol
"_declspec(dllimport)
public: __thiscall
stlpd_std::basic_string,class stlpd_std::allocator >::basic_string,class stlpd_std::allocator >(class stlpd_std::basic_string,class stlpd_std::allocator > const &)" (_imp??0?$basic_string#DV?$char_traits#D#stlpd_std##V?$allocator#D#2##stlpd_std##QAE#ABV01##Z) referenced in function "public: __thiscall Springfield::generic::runtime_error::runtime_error(class stlpd_std::basic_string,class stlpd_std::allocator > const &)" (??0runtime_error#generic#Springfield##QAE#ABV?$basic_string#DV?$char_traits#D#stlpd_std##V?$allocator#D#2##stlpd_std###Z)
for a more human readable version(replacing all the strings):
error LNK2019: unresolved external symbol
"__declspec(dllimport)
public: __thiscall
string::basic_string,class stlpd_std::allocator >(class string const &)" (_imp??0?$basic_string#DV?$char_traits#D#stlpd_std##V?$allocator#D#2##stlpd_std##QAE#ABV01##Z) referenced in function "public: __thiscall Springfield::generic::runtime_error::runtime_error(class string const &)" (??0runtime_error#generic#Springfield##QAE#ABV?$basic_string#DV?$char_traits#D#stlpd_std##V?$allocator#D#2##stlpd_std###Z
The sceond class of errors complains about
unresolved external symbol __CrtDbgReportW
I hope I can get some kind of insight in dealing with this.
From the errors it looks like you are not including the CRT as one of your linked libraries. Here is a link to the different CRT lib's offered in Visual Studio 2005. Choose the one which is most appropriate and make sure it's in the list of lib's to link against
http://msdn.microsoft.com/en-us/library/abx4dbyh(VS.80).aspx
It looks like you're either including a file that's been built using the debug settings or you're mixing runtime libraries (DLL and static).

How do you "decode" Visual Studio Link Errors?

I'm not very experienced in C++, and when I have to work with another library and I get link errors, I'm completely in the dark on what the compiler is trying to tell me (other than it can't find something reference somewhere).
Are there any good links that describe, in detail, the meaning of the symbols and characters in a link error message? Or how to trouble shoot such errors?
For example, this is a link error I received recently:
testproj error LNK2019: unresolved
external symbol "public: __thiscall
google::protobuf::internal::GeneratedMessageReflection::GeneratedMessageReflection(class
google::protobuf::Descriptor const
*,class google::protobuf::Message const *,int const *
const,int,int,int,class
google::protobuf::DescriptorPool const
*,int)" (??0GeneratedMessageReflection#internal#protobuf#google##QAE#PBVDescriptor#23#PBVMessage#23#QBHHHHPBVDescriptorPool#23#H#Z)
referenced in function "void __cdecl
testproj::protobuf_BuildDesc_def_2eproto_AssignGlobalDescriptors(class google::protobuf::FileDescriptor const
*)" (?protobuf_BuildDesc_def_2eproto_AssignGlobalDescriptors#testproj##YAXPBVFileDescriptor#protobuf#google###Z)
The symbols are the "mangled" versions of the function names. Basically because of c++ overloading (2 functions with different signatures can have the same name). The signature information is encoded into the name.
The message you pasted has both the encoded and plain text versions.
public: __thiscall google::protobuf::internal::GeneratedMessageReflection::GeneratedMessageReflection(class google::protobuf::Descriptor const *,class google::protobuf::Message const *,int const * const,int,int,int,class google::protobuf::DescriptorPool const *,int)
?0GeneratedMessageReflection#internal#protobuf#google##QAE#PBVDescriptor#23#PBVMessage#23#QBHHHHPBVDescriptorPool#23#H#Z)
are the same thing, just the later is mangled.
Notice that the mangled version starts with:
?0GeneratedMessageReflection#internal#protobuf#google
which corresponds nicely with:
google::protobuf::internal::GeneratedMessageReflection
Because the first few lines give you the relevant information, you can pretty much ignore the mangled versions. The plain text versions of the signatures are sufficient to fix the linker error.
Unresolved externals mean you are trying to call a function in another DLL, but you haven't linked to that DLL's LIB file.
It is usually pretty simple figuring out how to resolve these linker errors. The error message tells you exactly what you need to know:
google::protobuf::internal::GeneratedMessageReflection::GeneratedMessageReflection(class
google::protobuf::Descriptor const
*,class google::protobuf::Message const *,int const *
const,int,int,int,class
google::protobuf::DescriptorPool const
*,int)"
This looks like you are trying to use a class named "GeneratedMessageReflection" in a google library. Find out what library provides this class and then go in to your compilers linker settings & add an "Additional Reference" to that library's LIB file.