Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Link issues (VC6)

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.

like image 839
graham.reeds Avatar asked Aug 08 '08 13:08

graham.reeds


2 Answers

One possibility lies with Win32 ANSI/Unicode "name-mangling", which turns the symbol GetMessage into either GetMessageA or GetMessageW. There are three possibilities:

  1. Windows.h hasn't been loaded, so GetMessage stays GetMessage

  2. Windows.h was loaded with symbols set for ANSI, so GetMessage becomes GetMessageA

  3. 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 :(

like image 134
Curt Hagenlocher Avatar answered Nov 03 '22 09:11

Curt Hagenlocher


@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).

like image 34
graham.reeds Avatar answered Nov 03 '22 11:11

graham.reeds