LNK2001 error when compiling applications that reference STLport-5.1.4 with VC ++ 2008

I apologize in advance for the long post ...

I used to be able to build our VC ++ solutions (we are on VS 2008) when we listed the include directories and STLPort libraries in the VS menu> Tools> Options> VC ++ Directories> Directories for Include and Library files. However, we wanted to move on to a build process that makes full use of the .vcproj and .sln files. They can be checked in the initial control, unlike the VS-parameters, which must be configured on each development computer separately. We handled the transition for most libraries by adding Include directories to each project properties page> Configuration Properties> C / C ++> General> Additional Include Directories and Library Directories in Linker> General> Additional Library Directories.

Unfortunately, this approach does not work for STLPort. When binding, we get errors LNK2019 and LNK2001:

Error 1 error LNK2019: unresolved external symbol "public: virtual bool __thiscall MyClass::myFunction(class stlp_std::basic_istream<char,class stlp_std::char_traits<char> > &,class MyOtherClass &,class stlp_std::basic_string<char,class stlp_std::char_traits<char>,class stlp_std::allocator<char> > &)const " ( ?myFunction@MyClass @@ UBE_NAAV?$basic_istream@DV ?$char_traits@D @ stlp_std@ @@ stlp_std@ @ AAVSbprobScenarioData@ @ AAV?$basic_string@DV ?$char_traits@D @ stlp_std@ @ V?$allocator@D @ 2@ @ 3@ @Z) referenced in function _main MyLibrary.obj Error 5 error LNK2001: unresolved external symbol "public: static void __cdecl MyClass::myFunction(class stlp_std::basic_string<char,class stlp_std::char_traits<char>,class stlp_std::allocator<char> > const &,class stlp_std::basic_string<char,class stlp_std::char_traits<char>,class stlp_std::allocator<char> > const &,class stlp_std::basic_string<char,class stlp_std::char_traits<char>,class stlp_std::allocator<char> > const &,class stlp_std::basic_string<char,class stlp_std::char_traits<char>,class stlp_std::allocator<char> > const &,long,enum MyClass::MessageType,int,class stlp_std::basic_string<char,class stlp_std::char_traits<char>,class stlp_std::allocator<char> > const &)" ( ?myFunction@MyClass @@ SAXABV?$basic_string@DV ?$char_traits@D @ stlp_std@ @ V?$allocator@D @ 2@ @ stlp_std@ @ 000JW4MessageType@1 @ H0@Z ) MyLibrary.lib 

This happens when linking and executing a project with dependencies, which are library projects. Curiously, this does not happen, linking the library projects themselves. Any ideas?

+2
source share
6 answers

Raymond Chen recently talked about this in The Old New Thing - one of the reasons for these problems is that the library was compiled with one set of switches, but your application uses a different set. What you need to do:

Get the exact character that the linker is looking for. It will be a terrible perverted name. Use the hex editor (IIRC, Visual Studio will do this) to look at the .lib file you are linking to. Find a character that is almost the one the linker is looking for, but not quite. Given the differences in characters, try to figure out which command line options will help. Good luck - for people who are not used to such problems, the solution may take several days to find out (!)

+3
source

As mentioned in other answers, this is a linker error and probably the result of a library and application compiled with various parameters. There are several solutions to track this already (one of them as the chosen answer, for now). These solutions will work. However, there are several tools that will greatly simplify the search .

For starters, understanding decorated names will help. Inside all this garbage you will learn some things: the name of your function , namespaces , some types of classes that you use. All of these characters around them mean something to the compiler, but you don't need a compiler to tell you what they are.

Type undname.exe:


undname.exe <decorated name>
  • is a simple command line program that is located in your bin VS directory.
  • takes a name embellished as the first argument.
  • displays human readable character format.

Armed with this knowledge, you can proceed to the search for a reasonable candidate for an incorrectly created symbol.

First, you can edit your libraries in a hex editor, as suggested elsewhere. However, it is much easier to find characters.

Type dumpbin.exe:


dumpbin.exe <switches> <library name>
  • is a simple command line program that is located in your VS bin directory.
  • accepts a set of switches and a library for their application.
  • displays information from the library

The switch that interests you is / linkermember. There are many other switches that can get you very interesting information, but this list will list all the characters in the library.

A well-known command line command will help you at this point. Tools like grep can really shorten your work cycle, but you can get by with redirecting to a file and using notepad or the like.

Since I donโ€™t have your code or library, Iโ€™ll come up with an example from TinyXML.

Assuming your error message:

 Error 1 error LNK2019: unresolved external symbol "public: unsigned char __cdecl TiXmlComment::Accept(bool,class TiXmlVisitor *) " ( ?Accept@TiXmlComment @@ ZBE_NPAVTiXmlVisitor@ @@Z) referenced in function _main MyLibrary.obj 

Having determined that this is a function in TinyXML, I can start looking for an inconsistent character. I will start by dumping the library binders. (Note that the switch is singular, it always gets me when I print it from memory!)

 >dumpbin /linkermember tinyxml.lib Microsoft (R) COFF/PE Dumper Version 8.00.50727.762 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file tinyxml.lib File Type: LIBRARY Archive member name at 8: / 4992E7BC time/date Wed Feb 11 08:59:08 2009 uid gid 0 mode B402 size correct header end 859 public symbols 16292 ??$_Allocate@D @ std@ @ YAPADIPAD@Z 16292 ??$_Char_traits_cat@U ?$char_traits@D @ std@ @@ std@ @ YA?AU_Secure_char_traits_tag@0 @XZ 16292 ??$copy_s@U ?$char_traits@D @ std@ @@ _Traits_helper@std @@ YAPADPADIPBDI@Z 16292 ??$copy_s@U ?$char_traits@D @ std@ @@ _Traits_helper@std @@ YAPADPADIPBDIU_Secure_char_traits_tag@1 @@Z 16292 ??$move_s@U ?$char_traits@D @ std@ @@ _Traits_helper@std @@ YAPADPADIPBDI@Z 16292 ??$move_s@U ?$char_traits@D @ std@ @@ _Traits_helper@std @@ YAPADPADIPBDIU_Secure_char_traits_tag@1 @@Z 16292 ??$use_facet@V ?$ctype@D @ std@ @@ std@ @ YAABV?$ctype@D @ 0@ABVlocale @ 0@ @Z 16292 ??0?$_String_val@DV ?$allocator@D @ std@ @@ std@ @ IAE@V ?$allocator@D @ 1@ @Z 16292 ??0?$_String_val@DV ?$allocator@D @ std@ @@ std@ @ QAE@ABV01 @@Z 

This is obviously too much to read, but we do not need it, we know what we are looking for, so we are just looking for it.

 >dumpbin /linkermember tinyxml.lib | grep Accept 529AE ?Accept@TiXmlComment @@ UBE_NPAVTiXmlVisitor@ @@Z 529AE ?Accept@TiXmlDeclaration @@ UBE_NPAVTiXmlVisitor@ @@Z 529AE ?Accept@TiXmlDocument @@ UBE_NPAVTiXmlVisitor@ @@Z 529AE ?Accept@TiXmlElement @@ UBE_NPAVTiXmlVisitor@ @@Z 529AE ?Accept@TiXmlText @@ UBE_NPAVTiXmlVisitor@ @@Z 529AE ?Accept@TiXmlUnknown @@ UBE_NPAVTiXmlVisitor@ @@Z 3 ?Accept@TiXmlComment @@ UBE_NPAVTiXmlVisitor@ @@Z 3 ?Accept@TiXmlDeclaration @@ UBE_NPAVTiXmlVisitor@ @@Z 3 ?Accept@TiXmlDocument @@ UBE_NPAVTiXmlVisitor@ @@Z 3 ?Accept@TiXmlElement @@ UBE_NPAVTiXmlVisitor@ @@Z 3 ?Accept@TiXmlText @@ UBE_NPAVTiXmlVisitor@ @@Z 3 ?Accept@TiXmlUnknown @@ UBE_NPAVTiXmlVisitor@ @@Z 

It is much easier to read. Considering our mistake, we are looking for the Accept TiXmlComment function. We could print grep additionally for this name if we had a lot of matches (for example, looking at the size function in stl!), But in this case we can select it from the list. Here we go to undname:

 >undname ?Accept@TiXmlComment @@ UBE_NPAVTiXmlVisitor@ @@Z Microsoft (R) C++ Name Undecorator Copyright (C) Microsoft Corporation. All rights reserved. Undecoration of :- " ?Accept@TiXmlComment @@ UBE_NPAVTiXmlVisitor@ @@Z" is :- "public: virtual bool __thiscall TiXmlComment::Accept(class TiXmlVisitor *)const " 

So, in this example, our application is looking for a function that returns an unsigned char , but the library has a function that returns bool .. p>

This is a contrived example, but it illustrates the technique used to track your problem. You are probably looking for a typedef type that is set differently based on your options.

The problem I ran into was time_t . In some libraries that I used, time_t used a 32-bit type as part of the internal representation. This library was generated by an older compiler, where it was by default. In VS 2005, time_t uses the 64-bit type by default. I needed to add a define _USE_32BIT_TIME_T preprocessor to compile it. I traced this question as I described.

I hope this helps someone solve this problem!

+5
source

These link errors suggest that some classes in your application either were not compiled using STLPort or were excluded from the assembly. They do not assume that you are not contacting STLport.

My guess is this:

  • The build parameters for MyClass somehow overwrite the parameters for the entire project for the include path, and so MyClass is created using the default C ++ STL implementation, not STLport. This should be easy to verify - run dumpbin against the object file and check the functions where the standard library in the stlp_ * namespace refers or not. If not, it is likely that the compiler is not picking the correct include path. I would also look at the command line with which the IDE calls the compiler. They can also be viewed using the C / C ++ configuration properties.
  • As mentioned in other posters, it is likely that MyClass will not be built, but this should be very easy to verify.
+1
source

You need to configure the STL port to use the built-in implementation of IOStreams.

Also, is there any specific reason why you are using STLPort? The default implementation of STL is recommended if you are not trying to make a cross-platform application, even then it is not needed in most cases.

+1
source

This is a link error. This is not related to your include paths.

You either forgot to add MyClass.cpp to your project, or you forgot to define these two functions.

The reason the error does not occur when library โ€œlinkingโ€ projects are related to the fact that library projects are not connected. This is just a bunch of OBJs that are combined by the LIB program into a library file.

0
source

Add the library name to the list of additional libraries for communication. Sorry, I donโ€™t need the latest version of VS to know exactly where it is going.

0
source

All Articles