简体   繁体   中英

C++ linker unresolved external symbols

I'm building an application against some legacy, third party libraries, and having problems with the linking stage. I'm trying to compile with Visual Studio 9. My compile command is:

cl -DNT40 -DPOMDLL -DCRTAPI1=_cdecl
-DCRTAPI2=cdecl -D_WIN32 -DWIN32 -DWIN32_LEAN_AND_MEAN -DWNT -DBYPASS_FLEX -D_INTEL=1 -DIPLIB=none -I. -I"D:\src\include" -I"C:\Program Files\Microsoft Visual Studio
9.0\VC\include" -c -nologo -EHsc -W1 -Ox -Oy- -MD mymain.c

The code compiles cleanly. The link command is:

link -debug -nologo -machine:IX86
-verbose:lib -subsystem:console mymain.obj wsock32.lib advapi32.lib
msvcrt.lib oldnames.lib kernel32.lib
winmm.lib [snip large list of
dependencies] D:\src\lib\app_main.obj
-out:mymain.exe

The errors that I'm getting are:

app_main.obj : error LNK2019:
unresolved external symbol
"_\_declspec(dllimport) public: void
__thiscall std::locale::facet::_Register(void)"
(__imp_?_Register@facet@locale@std@@QAEXXZ)
referenced in function "class
std::ctype<char> const & __cdecl
std::use_facet<class std::ctype<char>
(class std::locale const &)" (??$use_facet@V?$ctype@D@std@@@std@@YAABV?$ctype@D@0@ABVlocale@0@@Z)

app_main.obj : error LNK2019:
unresolved external symbol
"__declspec(dllimport)  public: static
unsigned int __cdecl
std::ctype<char>::_Getcat(class
std::locale::facet const * *)"
(__imp_?_Getcat@?$ctype@D@std@@SAIPAPBVfacet@locale@2@@Z)
referenced in function "class
std::ctype<char> const & __cdecl
std::use_facet<class std::ctype<char>
(class std::locale const &)" (??$use_facet@V?$ctype@D@std@@@std@@YAABV?$ctype@D@0@ABVlocale@0@@Z)

app_main.obj : error LNK2019:
unresolved external symbol
"__declspec(dllimport)  public: static
unsigned int __cdecl
std::ctype<unsigned
short>::_Getcat(class
std::locale::facet const * *)"
(__imp_?_Getcat@?$ctype@G@std@@SAIPAPBVfacet@locale@2@@Z)
referenced in function "class
std::ctype<unsigned short> const &
__cdecl std::use_facet<class std::ctype<unsigned short> >(class
std::locale const &)"
(??$use_facet@V?$ctype@G@std@@@std@@YAABV?$ctype@G@0@ABVlocale@0@@Z)

mymain.exe : fatal error LNK1120: 3
unresolved externals

Notice that these errors are coming from the legacy code, not my code - app_main.obj is part of the legacy code, while mymain.c is my source. I've done some searching around, and what that I've read says that this type of error is caused by a mismatch with the -MD switch between my code and the library that I'm linking to. Since I'm dealing with legacy code, a solution has to come from my environment. It's been a long time since I've done C++ work, and even longer since I've used Visual Studio, so I'm hoping that this is just some ignorance on my part. Any ideas on how to get these resolved?

These are standard library references. Make sure that all libraries (including the standard library) are using the same linkage. Eg you can't link statically while linking the standard lib dynamically. The same goes for the threading model used. Take special care that you and the 3rd party library use the same linkage options.

This can be a real pain in the *ss.

Check this on MSDN :

  • /MD Causes your application to use the multithread- and DLL-specific version of the run-time library.
  • /MT Causes your application to use the multithread, static version of the run-time library.

Note: "... so that the linker will use LIBCMT.lib to resolve external symbols"

So you'll need a different set of libraries.

How I went about finding out which libraries to link:

  1. Find a configuration that does link, and add /verbose option.
  2. Pipe the output to a text file.
  3. Try the configuration that doesn't link.
  4. Look in the verbose output from step 2 for the symbols that are unresolved ("_declspec(dllimport) public: void thiscall std::locale::facet::Register(void)" in your case) and find the used libraries.
  5. Add those libraries to the list of libraries you're linking to.

Old skool but it worked for me.

Jan

If you still wish to get the project to compile using VS2008 (or in the future) I can suggest using a binary editor to view the object file in question mainapp.obj .

Here is an example from a small project of mine.

The zdbException.obj contains the following excerpt

DEFAULTLIB:"libc
pmtd" /DEFAULTLI
B:"uuid.lib" /DE
FAULTLIB:"uuid.l
ib" /include:?id
@?$num_put@DV?$o
streambuf_iterat
or@DU?$char_trai
ts@D@std@@@std@@
@std@@2V0locale@
2@A /include:?id
@?$numpunct@D@st
d@@2V0locale@2@A
 /DEFAULTLIB:"LI
BCMTD" /DEFAULTL
IB:"OLDNAMES" /E
DITANDCONTINUE 

Note the entry /DEFAULTLIB:"LIBCMTD" . This indicates the object file was compiled with the static c run-time multi-threaded debug.

There is also the possibility that the functions referenced in the obj are deprecated in the standard run-time lib shipped with VS2008.

After trying to get this stuff to compile under VS 2008, I tried earlier versions of VS - 2005 worked with warnings, and 2003 just worked. I double checked the linkages and couldn't find any problems, so either I just couldn't find it, or that wasn't the problem.

So to reiterate, downgrading to VS 2003 fixed it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM