Anfängerproblem: Linker Error: LNK2005



  • Hi

    also ich würde gerne noch einmal diesen 1A support hier in anspruch nehmen. Und zwar bin ihc im Moment daran mich ein bissl mit C++ zu beschäftigen und betreib da ein bissl learing by doing. Im moment bin ihc an einem kleinen Programm mit dem ich mich zu einer Webseite verbinden möchte und ein paar sachen mit der Antwort machen möchte. Diese Gelegenheit möchte ich gleichzeitig dazu nutzen meinen Coding-Stil zu verbessern in dem ich Funktionen auslager und header dateien benutze (bisher war bei mir immer alles in ewig langen .cpp dateien xD ). Hier ist der zugehörige Code:

    Connection.h

    #ifndef Connection_h
    #define Connection_h
    
    #using <system.dll>
    #include <iostream>
    #include <windows.h>
    
    using namespace std;
    using namespace System;
    using namespace System::IO;
    using namespace System::Net;
    using namespace System::Text;
    using namespace System::Text::RegularExpressions;
    
    String^ requestContent(String^ uri, CookieContainer^ Cookies);
    
    #include "connectionFramework.cpp"
    
    #endif
    

    connectionFramework.cpp (mir is kein besserer name eingefallen^^)

    #using <system.dll>
    #include <iostream>
    #include <windows.h>
    
    using namespace std;
    using namespace System;
    using namespace System::IO;
    using namespace System::Net;
    using namespace System::Text;
    using namespace System::Text::RegularExpressions;
    
    String^ requestContent(String^ uri, CookieContainer^ Cookies)
    {
    	HttpWebRequest^ request = dynamic_cast<HttpWebRequest^>(WebRequest::Create(uri));
    	request->UserAgent = "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3 Creative ZENcast v2.01.01";
    	request->CookieContainer = Cookies;
    
    	HttpWebResponse^ response = dynamic_cast<HttpWebResponse^>(request->GetResponse());
    	Stream^ dataStream = response->GetResponseStream();
    	StreamReader^ reader = gcnew StreamReader( dataStream );
    	String^ responseContent = reader->ReadToEnd();
    	reader->Close();
    	dataStream->Close();
    	response->Close();
    
    	return responseContent;
    }
    

    Connection.cpp

    #include "Connection.h"
    
    //using namespace std;
    //using namespace System;
    //using namespace System::IO;
    //using namespace System::Net;
    //using namespace System::Text;
    //using namespace System::Text::RegularExpressions; die Using-Teile kann ihc ja weglassen wenn sie schon in der header datei stehen?
    
    int main()
    {
    	CookieContainer^ Cookies;
    
    	Regex^ jsEnabled = gcnew Regex("<input type=\"hidden\" name=\"jsEnabled\" id=\"jsEnabled\" value=\"(.*?)\"");
    	Regex^ formkey = gcnew Regex("<input type=\"hidden\" name=\"formkey\" value=\"(.*?)\"");
    	Regex^ iv = gcnew Regex("<input type=\"hidden\" name=\"iv\" value=\"(.*?)\"");
    	Regex^ checkcode = gcnew Regex("<input type=\"hidden\" name=\"checkcode\" value=\"(.*?)\"");
    
    	cout<<"================SVZ-Connector================"<<endl;
    
    	Console::Write(requestContent("http://google.de", Cookies));
    
    	return 0;
    }
    

    wenn ich jetzt versuche das zu Kompilieren kommt aber folgender fehler:

    1>connectionFramework.obj : error LNK2005: "class System::String ^ __clrcall requestContent(class System::String ^,class System::Net::CookieContainer ^)" (?requestContent@@YMP$AAVString@System@@P$AAV12@P$AAVCookieContainer@Net@2@@Z) ist bereits in Connection.obj definiert.
    1>connectionFramework.obj : error LNK2005: "class System::String ^ __clrcall requestContent(class System::String ^,class System::Net::CookieContainer ^)" (?requestContent@@$$FYMP$AAVString@System@@P$AAV12@P$AAVCookieContainer@Net@2@@Z) ist bereits in Connection.obj definiert.
    

    Woran könnte das liegen?

    MfG
    Chris



  • ChrisKringel schrieb:

    ...

    Connection.h

    ...#include "connectionFramework.cpp"
    

    ...

    Das solltest Du nicht tun - und brauchst es auch nicht.
    mit den "include-guards" ("#ifndef ... #define ....#endif") schützt Du zwar den Compiler ... nicht aber den Linker vor Doppeldefinitionen.
    Stattdessen: Header inkludieren!
    =>
    connectionframework.cpp

    ...#include "Connection.h"
    

    Noch ein Tipp: Es ist üblicher, das "Implementierungsfile" genauso zu nennen, wie den Header (natürlich bis auf die Endung).
    Hier also:
    Connection.h
    Connection.cpp (statt "connectionFramework.cpp")
    Ist nicht zwingend, hilft aber bei der Übersicht...

    Gruß,

    Simon2.



  • Wenn Du connection.cpp und connectionframework.cpp bereits in einem Projekt zusammengefasst hast, will der Compiler (bzw. der Linker) diese zu einem ausführbaren Programm zusammenfassen. Da Du in der connection.h die Datei connectionframework.cpp includest, wird der Inhalt zweimal übersetzt, nämlich einmal bei der Übersetzung von connectionframework.cpp selbst und einmal bei der Übersetzung von connection.cpp (über connection.h).

    Man bindet keine .cpp-Dateien in .h-Dateien ein.



  • Und bei zukünftigen Fragen zu C++/CLI (denn das machst du!) schau mal hier 'rein:

    http://www.c-plusplus.net/forum/viewforum-var-f-is-58.html
    🙂



  • Cool es funzt. Ich merke mir:

    #include ".h" in einer cpp: gut
    #include "
    .cpp" in einer .h: böse

    danke für die Hilfe
    chris



  • ChrisKringel schrieb:

    #include "*.cpp" in einer .h: böse

    #include "*.cpp" : böse - egal, wo ^^

    bb


Anmelden zum Antworten