c++ visual-studio-2008 visual-c++ linker stlport

Error LNK2001 al compilar aplicaciones que hacen referencia a STLport-5.1.4 con VC++ 2008



visual-studio-2008 visual-c++ (6)

Este es un error de enlace. No tiene que ver con sus rutas de inclusión.

O olvidó agregar MyClass.cpp a su proyecto u olvidó definir esas dos funciones.

El motivo por el cual el error no ocurre cuando se "vinculan" proyectos de biblioteca es que los proyectos de la biblioteca no están vinculados. Son simplemente un conjunto de OBJ que el programa LIB recopila en un archivo de biblioteca.

Me disculpo de antemano por la larga publicación ...

Solía ​​ser capaz de construir nuestras soluciones de VC ++ (estamos en VS 2008) cuando enumeramos los directorios de inclusión e biblioteca de STLPort en Menú VS> Herramientas> Opciones> Directorios VC ++> Directorios para archivos de inclusión y biblioteca. Sin embargo, queríamos hacer la transición a un proceso de compilación que dependa totalmente de los archivos .vcproj y .sln. Estos se pueden verificar en el control de fuente a diferencia de las opciones de VS que deben configurarse en cada PC de desarrollo por separado. Manejamos la transición para la mayoría de las bibliotecas agregando los directorios Incluir a las Páginas de propiedades de cada proyecto> Propiedades de configuración> C / C ++> General> Directorios de inclusión adicionales, y directorios de biblioteca a Enlazador> General> Directorios de biblioteca adicionales.

Desafortunadamente, este enfoque no funciona para STLPort. Obtenemos errores LNK2019 y LNK2001 durante la vinculación:

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

Esto sucede mientras se vinculan proyectos ejecutables a dependencias que son proyectos de biblioteca. Curiosamente, esto no ocurre al vincular los proyectos de la biblioteca. ¿Algunas ideas?


Agregue el nombre de la biblioteca a la lista de bibliotecas adicionales para vincular. Lo siento, no estoy al frente de una versión reciente de VS para saber exactamente a dónde va.


Estos errores de enlace sugieren que ciertas clases en su aplicación no se han compilado utilizando STLPort o se han omitido de la compilación. No sugieren que no esté enlazando con STLport.

Mis conjeturas serían las siguientes:

  • La configuración de compilación para MyClass sobrescribe de alguna manera la configuración de todo el proyecto para la ruta de inclusión y, por lo tanto, MyClass se está creando utilizando la implementación C ++ STL predeterminada y no STLport. Esto debería ser fácil de comprobar: ejecute dumpbin contra el archivo de objeto y compruebe las funciones allí en referencia a la biblioteca estándar en el espacio de nombres stlp_ * o no. Si no, es probable que el compilador no recoja la ruta de inclusión correcta. También echaré un vistazo a la línea de comandos con la que el IDE llama al compilador. Estos también se pueden ver a través de las propiedades de configuración de C / C ++.
  • Como también se mencionaron otros carteles, existe la posibilidad de que MyClass no se esté construyendo, pero debería ser muy fácil de verificar.

Debe configurar el puerto STL para usar la implementación nativa de IOStreams.

¿También hay alguna razón específica por la que utilizas STLPort? Se recomienda la implementación predeterminada de STL a menos que intente crear una aplicación multiplataforma, incluso así no es realmente necesaria en la mayoría de los casos.


Raymond Chen habló recientemente sobre esto en The Old New Thing . Una de las causas de estos problemas es que la biblioteca se compiló con un conjunto de conmutadores, pero su aplicación usa un conjunto diferente. Lo que tienes que hacer es:

Obtenga el símbolo exacto que el enlazador está buscando. Será un horrible nombre destrozado. Use un editor hexadecimal (IIRC, Visual Studio lo hará) para ver el archivo .lib al que está vinculando. Encuentra el símbolo que es casi lo que el vinculador está buscando, pero no del todo. Dadas las diferencias en los símbolos, intente descubrir qué cambios de línea de comando ayudarán. Buena suerte: para las personas que no están acostumbradas a este tipo de problema, la solución puede llevar días en resolverse (!)


Como se menciona en otras respuestas, este es un error del enlazador y probablemente el resultado de la biblioteca y la aplicación compilada con diferentes opciones. Ya hay algunas soluciones para rastrear esto (una de ellas es la respuesta elegida, actualmente). Estas soluciones funcionarán Sin embargo, hay algunas herramientas que harán que su búsqueda sea mucho más fácil .

Para empezar, entender nombres decorados ayudará. Dentro de toda esa basura, reconocerá algunas cosas: el nombre de su función , espacios de nombres , algunos tipos de clase que está utilizando. Todos esos personajes a su alrededor significan algo para el compilador, pero no es necesario que el compilador le diga cuáles son.

Introduzca undname.exe:

undname.exe <decoratedname>
  • es un programa de línea de comando simple que está en su directorio VS bin.
  • toma el nombre decorado como su primer argumento.
  • da como resultado un formato legible por humanos del símbolo.

Armado con ese conocimiento, ahora puede pasar a buscar un candidato razonable para el símbolo mal creado.

En primer lugar, podría editar sus bibliotecas en un editor hexadecimal, como se sugiere en otra parte. Sin embargo, hay una manera mucho más fácil de encontrar los símbolos.

Ingrese dumpbin.exe:

dumpbin.exe <switches> <nombre de la biblioteca>
  • es un programa de línea de comando simple que está en su directorio VS bin.
  • toma un conjunto de interruptores y una biblioteca para aplicarlos.
  • genera información de la biblioteca

El interruptor que te interesará para tu pregunta es / linkermember . Hay muchos otros conmutadores que pueden proporcionarle información muy interesante, pero esta lista todos los símbolos en la biblioteca.

En este punto, un poco de comprensión de línea de comandos te servirá bien. Las herramientas como grep realmente pueden acortar su ciclo de trabajo, pero puede funcionar redirigiendo a un archivo y usando un bloc de notas o similar.

Como no tengo tu código o biblioteca, crearé un ejemplo de TinyXML.

Suponiendo que tu mensaje de error fuera este:

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

Después de haber determinado que esta es una función en TinyXML, puedo comenzar a buscar el símbolo que no coincide. Empezaré por deshacerme de los miembros enlazadores de la biblioteca. (Tenga en cuenta que el cambio es singular, ¡esto siempre me da cuando lo escribo desde la memoria!)

>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

Obviamente, esto es demasiado para leer, pero no es necesario, sabemos lo que estamos buscando, así que solo lo buscaremos.

>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

Eso es mucho más fácil de leer. Mirando nuestro error, estamos buscando la función Aceptar de TiXmlComment. Podríamos grep la salida adicional para ese nombre, si tuviéramos muchas coincidencias (como mirar la función de tamaño en el stl!), Pero en este caso, podemos elegirlo fuera de la lista. Aquí es donde pasamos a 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 "

Entonces, en este ejemplo, nuestra aplicación está buscando una función que devuelva un char sin signo , pero la biblioteca tiene una función que devuelve un bool .

Este es un ejemplo artificial, pero ilustra la técnica a usar para rastrear su problema. Probablemente esté buscando un tipo typedef que se configure de manera diferente según sus opciones.

El problema donde me topé con esto fue con time_t . En algunas bibliotecas que estaba usando, time_t usaba un tipo de 32 bits como parte de su representación interna. Esta biblioteca se generó con un compilador anterior, donde ese era el valor predeterminado. En VS 2005, time_t usa un tipo de 64 bits de forma predeterminada. Tuve que agregar el preprocesador para definir _USE_32BIT_TIME_T para compilarlo. Seguí este problema exactamente como lo describí.

¡Espero que esto ayude a alguien a resolver este problema!