I've opened an old workspace that is a libray and its test harness. It used to work fine but now doesn't and older versions of the code don't work either with the same errors. I've tried recreating the project and that causes the same errors too. Nothing seems out of order in project settings and the code generated works in the main app.
I've stripped out most of the files and got it down to the bare minimum to generate the error. Unfortunately I can't post the project as this is used in production code.
The LNK2001 linker error I get usually means I've left off a library or forgot to implement a virtual function. However this is part of the standard template library - and is a header at that.
The code that is listed as having the problem in IOCompletionPort.obj doesn't actually use std::string
directly, but does call a class that does: Comms::Exception
accepts a std::string
and the value of GetLastError
or WSAGetLastError
.
The function mentioned in the error (GetMessage
) is implemented, but is a virtual function so other classes can override it if need be. However it appears that the compiler has made it as an Ansi version, but I can't find any options in the settings that would control that. I suspect that might be the problem but since there's very little in the way of options for the library I have no way of knowing for sure. However both projects to specify _MBCS in the compiler options.
--------------------Configuration: TestComms - Win32 Debug-------------------- Linking... Comms.lib(IOCompletionPort.obj) : error LNK2001: unresolved external symbol "public: virtual class std::basic_string,class std::allocator > __thiscall Comms::Exception::GetMessageA(void)const " (?GetMessageA@ Exception@Comms@@UBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) Debug/TestComms.exe : fatal error LNK1120: 1 unresolved externals Error executing link.exe.
TestComms.exe - 2 error(s), 0 warning(s)
Any suggestions? I've lost most of the morning to this and don't want to lose most of the afternoon too.
One possibility lies with Win32 ANSI/Unicode "name-mangling", which turns the symbol GetMessage
into either GetMessageA
or GetMessageW
. There are three possibilities:
Windows.h hasn't been loaded, so GetMessage
stays GetMessage
Windows.h was loaded with symbols set for ANSI, so GetMessage
becomes GetMessageA
Windows.h was loaded with symbols set for Unicode, so GetMessage
becomes GetMessageW
If you've compiled two different files in ways that trigger two different scenarios, you'll get a linker error. The error message indicates that the Comms::Exception
class was an instance of #2, above -- perhaps it's used somewhere that windows.h hasn't been loaded?
Other things I'd do in your place, just as a matter of routine:
1) Ensure that my include and library paths don't contain anything that I'm not expecting.
2) Do a "build clean" and then manually verify it, deleting any extra object files if necessary.
3) Make sure there aren't any hardcoded paths in include statements that don't mean what they meant when the project was originally rebuilt.
EDIT: Fighting with the formatting :(
@Curt: I think you came the closest. I haven't tested this but I think I sort of gave the answer in my original question.
GetMessage is a define in Windows.h wrapped in a ifndef block to switch between Ansi (GetMessageA) and Unicode (GetMessageW).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With