Today my colleague encountered a strange Lnk2001 error while using VS2003.net to build a project.
Here is the error snippet:
error LNK2019: unresolved external symbol "unsigned short * __stdcall _com_util::ConvertStringToBSTR(char const *)" (?ConvertStringToBSTR@_com_util@@YGPA_WPBD@Z) referenced in function "public: __thiscall _bstr_t::Data_t::Data_t(char const *)" (??0Data_t@_bstr_t@@QAE@PBD@Z)
error LNK2019: unresolved external symbol "char * __stdcall _com_util::ConvertBSTRToString(unsigned short *)" (?ConvertBSTRToString@_com_util@@YGPADPA_W@Z) referenced in function "public: char const * __thiscall _bstr_t::Data_t::GetString(void)const " (?GetString@Data_t@_bstr_t@@QBEPBDXZ)
I checked if the correct lib (comsuppw.lib) is included. But he already did.
The same code can pass build in VC2005. But in VC2003, it can’t. That’s interesting.
One possibility is the environment of VC2003 differs from VC2005. By making a rough search, I found they are almost same. After I googled this bug, a post inspires me. I forget to check the method’s return type and argument type.
Let take a look at the same errors in VC2005:
Error 5 error LNK2001: unresolved external symbol "char * __stdcall _com_util::ConvertBSTRToString(wchar_t *)" (?ConvertBSTRToString@_com_util@@YGPADPA_W@Z) XLRCreatorDll.obj
Error 6 error LNK2001: unresolved external symbol "wchar_t * __stdcall _com_util::ConvertStringToBSTR(char const *)" (?ConvertStringToBSTR@_com_util@@YGPA_WPBD@Z) XLRCreatorDll.obj
Compare the error msg in VC2005 and VC2003, we can see the return type and argument type is different:
char * __stdcall _com_util::ConvertBSTRToString(unsigned short *) ----VC2003
char * __stdcall _com_util::ConvertBSTRToString(wchar_t *) ----VC2005
What does this mean?
Yes, the wchar_t in VC2003 project is treated as unsigned short instead of wchar_t itself. We know in some old OS implementation, wchar_t is only typedef of unsigned short. But in new release, wchat_t is definitely a native data type to support Unicode.
Then we know, in VC2003, the compiler still treats wchar_t as unsigned short rather than a native data type. But the prototype in comsuppw.lib, it requires wchar_t.
Thus comes the very simple solution:
add /Zc:wchar_t to command line of compiler.
After adding this option, the annoying Lnk2001 disappears.