Fehler beim Ausführen des Linkervorganges



  • Hallo,

    ich habe ein merkwürdiges Problem, dass ich mir nicht erklären kann. Ich habe in meinem MFC Projekt eine neue Headerdatei eingefügt, in der ich begonnen habe, eine Klasse zu schreiben. Diese Headerdatei habe ich in StdAfx.h mittels #include hinzugefügt.

    Die Klasse sieht bisher so aus:

    class enModule
    {
    	public:
    		enModule();
    		void Create(CString);
    		CString& GetTitle();
    	private:
    		CString mtitle;
    };
    
    // Konstruktor
    enModule::enModule()
    {
    	mtitle="";
    }
    
    // Methoden
    void enModule::Create(CString title)
    {
    	mtitle=title;
    	return;
    }
    
    CString& enModule::GetTitle()
    {
    	return(mtitle);
    }
    

    Das #include des Headers ist in der StdAfx.h wie folgt angeordnet:

    ...
    #include <afxext.h>         // MFC-Erweiterungen
    #include <afxdtctl.h>		// MFC-Unterstützung für allgemeine Steuerelemente von Internet Explorer 4
    #include <vector>
    using namespace std;
    #include "defines.h"
    #include "enModule.h" //<<<---------------------
    #ifndef _AFX_NO_AFXCMN_SUPPORT
    #include <afxcmn.h>			// MFC-Unterstützung für gängige 
    ...
    
    //{{AFX_INSERT_LOCATION}}
    

    Nun bekomme ich beim Linken, jedoch nur gelegentlich, folgende Ausgabe:

    StdAfx.obj : error LNK2005: "public: __thiscall enModule::enModule(void)" (??0enModule@@QAE@XZ) bereits in enVisionedDlg.obj definiert
    StdAfx.obj : error LNK2005: "public: void __thiscall enModule::Create(class CString)" (?Create@enModule@@QAEXVCString@@@Z) bereits in enVisionedDlg.obj definiert
    Debug/enVisioned.exe : fatal error LNK1169: Ein oder mehrere mehrfach definierte Symbole gefunden
    Fehler beim Ausführen von link.exe.
    

    Ich habe das #include nirgendwo doppelt eingefügt oder so, ich nutze es nur einmal in StdAfx.h. Das Merkwürdige: Gelegentlich kompiliert und linkt das Projekt ohne Probleme, und ich kann es starten. Dann kommt es wieder zu dieser Fehlermeldung. Dazu muss ich auch nichts an den obigen Codes ändern, es reicht, wenn ich irgendwo etwas im Code verändere, auch an ganz anderer Stelle, damit der Fehler ausgelöst wird.

    Wer kann mir helfen?
    Danke für eure Zeit...



  • Ich bin mir nicht ganz sicher aber ich glaub du musst dann

    #include "afxext.h"
    

    anstatt

    #include <afxext.h>
    

    schreiben...musste mal ausprobieren bin mir aber wie gesagt net sicher.

    edit:
    oh ich hab mich verguggt aber ähm wo genau soll den die Datei includet werden? Ich find sie i-wie net...
    mfg the-coder



  • Nehme mal an du hast includeguards in "enModule.h".
    dann hast du 2 Möglichkeiten:
    entweder du schreibst die implementationen der methoden gleich in die Klassendeclaration oder du verwendest das keyword inline.
    Kurt



  • Danke für die Antworten...
    Tut mir leid, was sind "Includeguards"?
    Die Datei enModule.h ist so aufgebaut, wie der erste Codeschnippsel meines ersten Posts zeigt - enthält also die reine Klasse.



  • Dann mach's so

    #ifndef EN_MODULE_INCLUDED
    #define EN_MODULE_INCLUDED
    class enModule
    {
        public:
            enModule();
            void Create(CString);
            CString& GetTitle();
        private:
            CString mtitle;
    };
    
    // Konstruktor
    inline enModule::enModule() {
        mtitle="";
    }
    
    // Methoden
    inline void enModule::Create(CString title) {
        mtitle=title;
        return;
    }
    
    inline CString& enModule::GetTitle() {
        return(mtitle);
    } 
    #endif
    

    Kurt



  • Ok vielen Dank, das mit der Include-Abfrage verstehe ich.
    Ich habe aber noch eine Verständnisfrage: Wieso muss ich nun meine Klassenmethoden alle als inline deklarieren? Ist es nicht möglich, in MFC die Klassen ganz normal zu schreiben, so wie ich es sonst unter Verwendung der WinAPI auch täte? Das Ganze ist mir im Moment nicht ganz klar...



  • MFC-Noob schrieb:

    Ist es nicht möglich, in MFC die Klassen ganz normal zu schreiben, so wie ich es sonst unter Verwendung der WinAPI auch täte? Das Ganze ist mir im Moment nicht ganz klar...

    Das Problem is dass du die Methoden im Header implementierst. Wenn Sie nicht Inline deklariert sind nimmt der Compiler sie in jede compilation-unit auf. ( also in jede Objektdatei deren Source diesen Header includiert ). Der Linker mag das dann aber nicht weil er sich nicht entscheiden kann welche Version er verwenden soll. Schreibst du die Inplementation gleich in die Klassendeclaration ( implizit inline ) oder machst sie Inline gibts keine Konflikte.
    Du kannst die Implementationen natürlich auch ganz einfach in eine .cpp Datei schreiben und diese dazulinken.
    Kurt



  • Gut, dankeschön für deine ausführliche Antwort. Ich werde mich dann für Letzteres entscheiden, also die Implementation in eine *.cpp Datei schreiben.

    Danke nochmals.


Anmelden zum Antworten