Visual C++: STL in welcher library?



  • Hallo,
    ich programmiere mein C++ Zeugs mit Visual C++ 2008 Express Edition. Soweit so gut, hat bisher alles gut geklappt.

    Nun möchte ich std::vector benutzen. Also mache ich ein

    #include <vector>
    

    Ich kann den std::vector soweit benutzen, der Compiler meckert nicht, aber der Linker bringt den Fehler LNK2019. Bisher war die Lösung dieses Problems ganz einfach indem ich in den Projekteinstellungen unter "Konfigurationseigenschaften->Linker->Eingabe->Zusätzliche Abhängigkeiten" die zur Header-Datei gehörige .lib Datei noch mit angegeben habe.
    Welche Datei ich dort anzugeben hatte, habe ich leicht im Internet gefunden, meistens bei MSDN.

    Aber hier bei der STL komme ich irgendwie nicht weiter. Ich finde nirgends im Internet die dazugehörige *.lib Datei. Weiß jemand welche *.lib Datei ich dort angeben muss?

    Mir ist das sowieso irgendwie verdächtig, denn das was ich da benutzen will gehört doch zum C++ Standard oder nicht? Sowas muss man doch nicht extra angeben oder?

    Vielleicht muss ich aber auch in den Projekteinstellungen an einer anderen Stelle was anderes einstellen? Ich habe das Projekt mit einem Wizzard erstellt, möglicherweise hat dieser einen Mist zusammen konfiguriert...?!

    Ich wäre sehr dankbar wenn mir das jemand erklären könnte...

    MfG



  • Die STL ist eine Header- Only Library, d.h. nur aus Header Files bestehend.

    Dein Linker Problem ist vermutlich anders begründet. Zeige doch die exakte Fehlermeldung.

    Simon



  • SchlechterInformatiker schrieb:

    Ich kann den std::vector soweit benutzen, der Compiler meckert nicht, aber der Linker bringt den Fehler LNK2019.

    Gut, dass du uns so detailliert über den Wortlaut der Meldung informierst.





  • Du suchst den Fehler wahrscheinlich an der falschen Stelle. Mehr Code wäre hilfreich und eine detaillierte Fehlermeldung.



  • Sorry für die wenigen Informationen. War etwas unter Zeitdruck und dachte jemand kennt vielleicht das Problem.
    Hier hab ich den Code:

    StdAfx.h

    // stdafx.h : include file for standard system include files,
    //  or project specific include files that are used frequently, but
    //      are changed infrequently
    //
    
    #if !defined(AFX_STDAFX_H__80495E63_2DA6_11D4_A351_0050DAD61B65__INCLUDED_)
    #define AFX_STDAFX_H__80495E63_2DA6_11D4_A351_0050DAD61B65__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    // Insert your headers here
    #define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
    
    #include <windows.h>
    #include "A3d_List.h"
    #include "A3d_Channels.h"
    // TODO: reference additional headers your program requires here
    
    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
    
    #endif // !defined(AFX_STDAFX_H__80495E63_2DA6_11D4_A351_0050DAD61B65__INCLUDED_)
    

    Downloader.h

    #pragma once
    #include <vector>
    
    #ifdef DOWNLOADER_EXPORTS
    #define DOWNLOADER_API __declspec(dllexport)
    #else
    #define DOWNLOADER_API __declspec(dllimport)
    #endif
    
    #define DOWNLOADER_NAME		"Downloader"
    #define DOWNLOADER_VERSION		1
    
    //{D253B4DB-109A-43FF-BB0F-7C4D13BBFED6}
    static const GUID DOWNLOADER_GUID = { 0xD253B4DB, 0x109A, 0x43FF, { 0xBB, 0x0F, 0x7C, 0x4D, 0x13, 0xBB, 0xFE, 0xD6 } };
    
    class DOWNLOADER_API Downloader: public A3d_Channel
    {
    public:
    	Downloader();
    	virtual ~Downloader();
    protected:
    	std::vector<int> v;
    
    };
    
    // Leave rest of header file intact!
    #define DOWNLOADERDLL_EXPORTS extern "C" { \
    __declspec(dllexport) DllInterface * __cdecl InitDLL() \
    { \
    	return new Downloader; \
    } \
    }
    

    StdAfx.cpp

    // stdafx.cpp : source file that includes just the standard includes
    //	Float.pch will be the pre-compiled header
    //	stdafx.obj will contain the pre-compiled type information
    
    #include "stdafx.h"
    
    // TODO: reference any additional headers you need in STDAFX.H
    // and not in this file
    

    Downloader.cpp

    // Array_Buffer.cpp : Defines the entry point for the DLL application.
    //
    
    #include "stdafx.h"
    #include "Downloader.h"
    ChannelType channelType;
    
    extern "C" __declspec( dllexport ) ChannelType* __cdecl GetType() {
    	ZeroMemory(channelType.name, 80);
    	StringCbCopy(channelType.name,  79, DOWNLOADER_NAME); 
    	channelType.version			= DOWNLOADER_VERSION;
    	channelType.guid			= DOWNLOADER_GUID;
    	channelType.baseguid		= DOWNLOADER_GUID;
    	channelType.minimumEdition 	= EDITION_LEVEL_ALL;		// All Quest3D Editions
    
    	return &channelType;
    }
    
    DOWNLOADERDLL_EXPORTS
    
    Downloader::Downloader() {
    	SetChannelName(DOWNLOADER_NAME);
    	//TODO: Add construction logic here
    }
    
    Downloader::~Downloader()
    {
    	//TODO:: Add destruction logic here
    }
    

    So sieht eigentlich der Code aus, der vom Wizzard erzeugt wurde (habe nur der Übersicht halber vier weitere Klassen-Methoden entfernt, die sowieso nur einen leeren Rumpf hatten). Sobald ich die Zeile

    std::vector<int> v;
    

    in Downloader.h einfüge, kommt dieser Fehler:

    1>Downloader.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> >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z)".
    

    Wenn ich ein Standard-Projekt erstelle, z.B. eine Konsolenanwendung (Datei->Neu->Projekt... dann Visual C++->Win32->Win32-Konsolenanwendung) dann kann ich std::vector ohne Probleme benutzen.

    Weiß jemand Rat? Sonst muss ich wohl jede einzelne Projekteinstellung mal umstellen und neu zu compilen versuchen... und das sind ja einige. Ich wüsste gar nicht wo ich anfangen soll 😮



  • Schau mal in den Projekteigenschaften unter Konfigurationseigenschaften -> Linker -> Eingabe, ob der Wizard "Standardbibliotheken ignorieren" auf "Ja" gesetzt hat. Das könnte so ein Verhalten erklären.

    Prinzipiell ist der größte Teil der STL Header-Only, aber ein paar Objekte gibt es doch (std::cout beispielsweise), und in aller Regel liefert die Laufzeitbibliothek für die gängigsten Varianten, beispielsweise std::string, explizite Konkretisierungen mit.

    Allerdings bin ich mir unsicher, warum die Verwendung von std::vector<int> Symbole von std::string braucht.



  • Das hat scheinbar nichts mit vector zu tun, da der Linker ja std::string anmeckert.
    Könnte das aus der Basisklasse von DOWNLOADER_API Downloader stammen?


  • Administrator

    Oder fügst du ein std::vector<std::string> ein? Und hast nirgends ein #include <string> hingesetzt?

    Grüssli



  • LNK2001 ist aber ein Linker Fehler, kein Compiler Fehler.
    Mit "ignore default libraries" gäbe es auch sicher noch mehr Fehlermeldungen vom Typ LNK2001, da vector auch bspw. new, delete etc. benötigt.



  • Hab gerade zufällig herausgefunden dass es funktioniert wenn ich das Projekt unter 'Debug' erstelle. Nur unter 'Release' geht's nicht - selber Code...
    also an der Basisklasse dürfte es somit nicht liegen...?!

    Nein, ich benutze nicht std::vectorstd::string sondern ein std::vector<int>
    Es werden keine Bibliotheken ignoriert, weder unter 'Debug' noch unter 'Release'

    Ich werd mal die beiden Projekteinstellungen zwischen 'Debug' und 'Release' vergleichen... irgendwo da muss die Antword sein, hoffe ich...

    Also hier hab ich die Unterschiede in den Projekteinstellungen zwischen 'Release' und 'Debug':

    C/C++ ->Allgemein->Debuginformationsformat	       		Release:'Deaktiviert'				       Debug:'<Vom übergeordneten Projekt erben oder Projektstandard>'
    C/C++ ->Optimierung->Optimierung	       	 		     Release:'Geschwindigkeit maximieren(/O2)	Debug:'Deaktiviert(/Od)'
    C/C++ ->Optimierung->Inlinefunktionserweiterung              Release:'Nur __inline(/Ob1)                 Debug:'Standard'
    C/C++ ->Präprozessor->Präprozessordefinitionen	       	Release:'NDEBUG'				            Debug:'_DEBUG'
    C/C++ ->Codegenerierung->Stringpooling aktivieren       	 Release:'Ja(/GF)'               			Debug:'Nein'						
    C/C++ ->Codegenerierung->Vollständige Laufzeitüberprüfung	Release:'Standard'				          Debug:'Beide(/RTC1 entspricht /RTCsu)'						
    C/C++ ->Codegenerierung->Laufzeitbibliothek	      		Release:'Multithreaded-DLL(/MD)'		    Debug:'Multithreaded-Debug-DLL(/MDd)'
    C/C++ ->Codegenerierung->Funktionslevel-Linking aktivieren   Release:'Ja(/Gy)'				           Debug:'Nein'
    Linker->Debugging->Debuginfo ignorieren	      			Release:'Nein'					          Debug:'Ja(/DEBUG)'
    


  • Ok, ich hab die Einstellung gefunden:
    Es funktioniert nicht wenn C/C++ ->Codegenerierung->Laufzeitbibliothek auf Multithreaded-DLL(/MD) eingestellt ist. Stell' ich es um auf Multithreaded-Debug-DLL(/MDd) oder irgendeine andere Oprion, dann funktioniert es...

    Ist das nun ein Problem wenn ich Multithreaded-Debug-DLL(/MDd) benutze? Wird mein Programm dann langsam oder sowas?

    Trotzdem schon mal vielen Dank für die vielen Anregungen und Hilfen!!
    MfG



  • SchlechterInformatiker schrieb:

    Ist das nun ein Problem wenn ich Multithreaded-Debug-DLL(/MDd) benutze? Wird mein Programm dann langsam oder sowas?

    Du kannst nicht davon ausgehen das andere die Debugversion auf dem Rechner haben (wenn die Weitergabe der Debugbibliotheken Lizenztechnisch überhaupt ohne Compiler zulässig ist). Langsamer wird es vermutlich ebenso sein.



  • der fehler kann kommen, wenn Du eine Lib dazu linkst, die nicht mit dem entsprechenden Modell übersetzt wurde. Die linkt dann schon vorher gegen die - in Deinem Fall - Debug Version der DLL und nachher stolpert der Linker darüber.

    Du solltest für alle Bibliotheken überprüfen, ob Du die mit dem richtigen Modell hast. Ich mache das als Hilfe für mich immer so, dass ich an den Lib Namen das Modell anhänge (myLibMT, myLibMTD)


Anmelden zum Antworten