Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. string

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. string

Beitrag von Eisflamme »

Hallo,

Ich habe das Problem, dass ich seit der Umstellung meiner Projektmappe von VC++ Express Edition 2008 auf 2010 Fehlermeldungen bzgl. der Klasse string erhalte.

Dieses Projekt nutzt über eine .lib und Header assimp. Dieses nutzt string anscheinend auch und wirft mir letztendlich auch die Fehlermeldungen.

Zunächst ein paar Warnungen, die interessant sein können:

Code: Alles auswählen

1>assimp.lib(XFileParser.obj) : warning LNK4049: Lokal definiertes Symbol "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ (public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void))" wurde importiert.
1>assimp.lib(DefaultIOStream.obj) : warning LNK4049: Lokal definiertes Symbol "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ (public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void))" wurde importiert.
1>assimp.lib(ObjFileMtlImporter.obj) : warning LNK4217: Lokal definiertes Symbol "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ (public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void))" wurde in "unsigned __int64 __cdecl Assimp::strtol10_64(charconst *,char const * *,unsigned int *)" (?strtol10_64@Assimp@@YA_KPBDPAPBDPAI@Z)-Funktion importiert.
1>assimp.lib(ASEParser.obj) : warning LNK4049: Lokal definiertes Symbol "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ (public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void))" wurde importiert.
1>assimp.lib(PlyParser.obj) : warning LNK4049: Lokal definiertes Symbol "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ (public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void))" wurde importiert.
1>assimp.lib(3DSConverter.obj) : warning LNK4049: Lokal definiertes Symbol "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ (public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void))" wurde importiert.
1>assimp.lib(ObjFileParser.obj) : warning LNK4049: Lokal definiertes Symbol "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ (public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void))" wurde importiert.
1>assimp.lib(LWOBLoader.obj) : warning LNK4049: Lokal definiertes Symbol "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ (public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void))" wurde importiert.
1>assimp.lib(SGSpatialSort.obj) : warning LNK4049: Lokal definiertes Symbol "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ (public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void))" wurde importiert.
und viele ähnliche...

Und dann habe ich die Fehler:

Code: Alles auswählen

1>assimp.lib(MD2Loader.obj) : error LNK2001: Nicht aufgelöstes externes Symbol ""__declspec(dllimport) public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(struct std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Has_debug_it)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)".
1>assimp.lib(MD3Loader.obj) : error LNK2001: Nicht aufgelöstes externes Symbol ""__declspec(dllimport) public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(struct std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Has_debug_it)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)".
1>assimp.lib(3DSLoader.obj) : error LNK2001: Nicht aufgelöstes externes Symbol ""__declspec(dllimport) public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(struct std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Has_debug_it)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)".
1>assimp.lib(SMDLoader.obj) : error LNK2001: Nicht aufgelöstes externes Symbol ""__declspec(dllimport) public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(struct std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Has_debug_it)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)".
1>assimp.lib(HMPLoader.obj) : error LNK2001: Nicht aufgelöstes externes Symbol ""__declspec(dllimport) public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(struct std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Has_debug_it)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)".
1>assimp.lib(ASELoader.obj) : error LNK2001: Nicht aufgelöstes externes Symbol ""__declspec(dllimport) public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(struct std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Has_debug_it)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)".
1>assimp.lib(MDLLoader.obj) : error LNK2001: Nicht aufgelöstes externes Symbol ""__declspec(dllimport) public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(struct std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Has_debug_it)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)".
1>assimp.lib(LWOLoader.obj) : error LNK2001: Nicht aufgelöstes externes Symbol ""__declspec(dllimport) public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(struct std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Has_debug_it)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)".
1>assimp.lib(STLLoader.obj) : error LNK2001: Nicht aufgelöstes externes Symbol ""__declspec(dllimport) public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(struct std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Has_debug_it)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)".
1>assimp.lib(MD5Loader.obj) : error LNK2001: Nicht aufgelöstes externes Symbol ""__declspec(dllimport) public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(struct std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Has_debug_it)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)".
1>assimp.lib(MDCLoader.obj) : error LNK2001: Nicht aufgelöstes externes Symbol ""__declspec(dllimport) public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(struct std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Has_debug_it)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)".
1>assimp.lib(OFFLoader.obj) : error LNK2001: Nicht aufgelöstes externes Symbol ""__declspec(dllimport) public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(struct std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Has_debug_it)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)".
Sind jetzt beides nur so Ausschnitte.

Ja, mir fällt nicht so viel ein. <string> ist inkludiert und mit VC++08 hat's geklappt. Jemand eine Idee?

Danke im Voraus!
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. st

Beitrag von Schrompf »

Vermutung 1: Assimp wurde noch mit VC2008 gebaut. Du kannst keine Lib, die mit VC2008 gebaut ist, in eine mit VC2010 gebaute Exe einbinden. Kompiliere Assimp neu mit VC2010.
Vermutung 2: Abweichende Runtimes. Schau in die Projekteinstellungen, ob die CRT-Einstellungen *exakt* übereinstimmen. Ich kenne die exakten Namen jetzt nicht, da ich auf dem Rechner hier kein VC drauf hab, aber Du müsstest üblicherweise sowas wie "DLL-Multithreaded Debug" für Debug-Builds eingestellt haben.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. st

Beitrag von Eisflamme »

Das Problem ist, das Projekt wurde konvertiert, daher habe ich auf das alte keinen Zugriff mehr. Ist aber alles multithreaded Debug DLL, sollte daher kein Problem sein.

Um assimp mit VC10 zu kompilieren, müsste er überhaupt erstmal das Projekt konvertieren können. Leider funktioniert das nicht, weil's Fehler gibt... Muss das wohl Stück für Stück übertragen, könnte natürlich in Arbeit ausarten...
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. st

Beitrag von Aramis »

>> Dieses Projekt nutzt über eine .lib und Header assimp

Nimm unbedingt einen DLL-Build von Assimp, ueber eine statische Lib kann es nicht klappen sofern Assimp nicht gegen exakt die gleiche Runtime mit exakt dem gleichen Setup kompiliert wurde.

Der DLL-Build wird auch funktionieren wenn dein Hauptprojekt VC10 und dessen Runtime nutzt.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. st

Beitrag von kimmi »

Du kannst dir die VC10-Project-Files recht einfach per cmake generieren lassen:
  • CMake herunterladen und installieren.
  • Sicherstellen, dass das Bin-Directory der CMake-Installation in deiner PATH-Enviroment-Variable drinn ist. Das macht der Installer zwar sowieso, aber sicher ist sicher. In einer neuen Konsole nach der erfolgreichen Installation set eingeben und die PATH-Variable darauf überprüfen.
  • In das Assimp-Source-Verzeichnis wechseln und cmake CMakeLists.txt eingeben und loslegen.
Danach generiert er dir ein valides Projectfile. Allerdings muss zur Zeit boost installiert sein.

Gruß Kimmi
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. st

Beitrag von Eisflamme »

Hi,

Bevor ich das neukompiliere, würde ich natürlich schon gerne dynamisch linken, sofern das geht, also halt nicht über die .lib, vielleicht löst das mein Problem ja schon.

Mag jetzt ne doofe Frage sein, aber wie mach ich das?

Viele Grüße
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. st

Beitrag von kimmi »

Die Dll entweder implizit oder explizit laden. Also Dll von Assimp implizit beim Start laden lassen, in dem du die ExportLib in deiner Anwendung linkst. Oder du lädst die Dll explizit per LoadLibrary, die jeweiligen FunctionPointer der Symbole kannst du dann per GetProcAdress holen.

Gruß Kimmi
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. st

Beitrag von Aramis »

Nicht dass wir uns falsch verstehen: die .Lib wird im Buildprozess praktisch immer benoetigt. Allerdings hast du nie spezifiziert, ob du versuchst gegen die DLL zu linken (d.h. die Lib forwarded Assimp–Aufrufe auf die DLL) oder Assimp statisch einzubetten (die Lib enthaelt Objektcode). Von letzterem wuerde ich abraten.

Die geposteten Fehlermeldungen deuten darauf hin, dass du versuchst gegen eine Lib von der letzteren Sorte zu linken -- die 'richtige' Datei sollte nicht groesser als 250KiB sein.

Sollte diese Vermutung zutreffen, lautet die Loesung: Du kompilierst Assimp mit VC9 neu, release-dll. In /lib/assimp_release-dll_<platform> findest du dann die passende Importbibliothek.
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. st

Beitrag von Eisflamme »

Hi,

Also ich habe mir jetzt spaßeshalber Mal das neuste Assimp geladen und damit funktioniert jetzt plötzlich alles? Gelinkt habe ich wohl statisch, weil ich die .lib über Projekteigenschaften->Eingabe eintrage. Ist eine Schreibweise wie "#pragma comment(lib, "../Debug/Engine.lib")" auch statisch oder dynamisch?

Lediglich eines ist seltsam:
Ich gebe bei den Verzeichnissen bei lib das Debug-Verzeichnis an, das Projekt fordert allerdings eine assimp32.dll, sodass ich das /bin/release-Verzeichnis angeben muss, da die Debug-DLLs assimp32d.lib heißen. Hab ich da n gedanklichen Fehler?

Und weiß jetzt noch einer zufällig, welche Verzeichnisart ich um das Assimp-/bin/ Verzeichnis erweitern muss in VC++, damit ich die DLL nicht hart kopieren muss, weil er sonst über das Fehlen dieser meckert? Dann wäre mein Tag echt gerettet. :)

Vielen Dank schon Mal für eure Hilfe. Es ist echt unglaublich, wie schnell hier geantwortet wird...
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. st

Beitrag von Aramis »

Du musst sie ins Verzeichnis deiner EXE kopieren. Allenfalls das Working Directory auf den Pfad der DLL setzen, aber DAS ist definitiv keine gute Idee. Fuer die Suchreihenfolge, siehe:

http://msdn.microsoft.com/en-us/library ... S.85).aspx
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. st

Beitrag von Eisflamme »

Ah, interessant. Hab den Artikel Mal überflogen. Anscheinend gibt es ein paar Möglichkeiten, wenn ich das über LoadLibrary(...) bewerkstellige. Aber da auch dort der Pfad fix wäre, spar ich mir das lieber und kopiere die DLL halt eben.

Danke :)
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. st

Beitrag von Aramis »

Gelinkt habe ich wohl statisch, weil ich die .lib über Projekteigenschaften->Eingabe eintrage
Du bringst die Begrifflichkeiten durcheinander. Es gibt insgesamt 3 Moeglichkeiten:
  • 1. Komplett statisch. Du nutzt eine LIB, die Assimp in vorkompilierter Form enthaelt. Das wird vom Linker einfach mit in dein Hauptprogramm hineingelinkt.
  • 2. Halb-dynamisch*. Du nutzt eine LIB, die Verweise auf eine DLL enthaelt. Rufst du eine der darin aufgelisteten Funktionen auf, wandert der entsprechende Eintrag in die Importtabelle der EXE. Beim Programmstart sucht der PE-Loader dann nach den benoetigten Abhaengigkeiten und laedt die passenden DLLs in den Adressraum.
  • 3. Dynamisch. Du nutzt das OS-API (LoadLibrary) um die DLL zu laden, besorgst dir dann manuell Funktionsadressen aus ihrer Exporttabelle (GetProcAddress). Die rufst du dann auf.
* Im Normalfall meint 'dynamisches Linken' die zweite Form, auch wenn das streng genommen nicht ganz stimmt.

Fall 1 und 2 nutzen eine LIB-Datei, die explizit beim Build als Abhaengigkeit einzutragen ist. Aber sie nutzen sie fuer voellig unterschiedliche Zwecke. Variante 3 ist unueblich, weil muehsam. Eigentlich nur dann noetig, wenn du dir nicht sicher bist ob die DLL, die du benoetigst, auf dem Zielsystem verfuegbar ist (Es gibt genau genommen auch noch eine Variante zwischen 2 und 3 – Delay–Loading, aber die habe ich mal ignoriert).
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: Umstellung VC++08 -> VC++10: Nicht aufgel. ext. Symb. st

Beitrag von Eisflamme »

Hi,

Ah, okay, danke. Jetzt versteh ich das besser. :) Wenn ich halt nur die lib habe, hab ich ja keine Wahl, assimp so oder so zu verwenden, oder? Es sei denn, ich kompiliere halt selbst.

Na wie auch immer, es klappt ja jetzt. :)
Antworten