(Dateien nach einer bestimmten Reihenfolge kompilieren) Linker-Fehler



  • Hallo,

    ich habe ein Frage, und zwar ob es in VS2008 die Möglichkeit gibt, die Dateien nach einer Reihenfolge zu kompilieren. Ich habe schon danach gesucht, hab aber nichts gefunden.

    Hoffe auf eine schnelle Antwort
    MFG
    DieTuer



  • denke nicht, aber wozu soll das gut sein?



  • 1.Datei

    //ieInitWindow.h
    //Initialisieren des Fensters
    #pragma once
    
    //Funktionen
    LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    ieResult InitWindow(int iWidth, int iHeight, char* cName, HICON hIcon);
    ieResult ExitWindow();
    ieResult MessageLoop(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    

    2.Datei

    //IEngine.h
    //Funktion:	Headerdatei der Engine	
    #pragma once
    
    #include <Math.h>
    ...
    #include <Windows.h>
    
    [...]
    enum ieResult
    {
    	IE_OK			=	0,
    	IE_ERROR		=	1,
    	IE_CANCELED		=	2,
    	IE_NOT_FOUND	=	3,
    	IE_STOP			=	4,
    };
    
    [...]
    
    //Die einzelnen Bestandteile hinzufügen
    #include "ieInitWindow.h"
    #include "ieVector3.h"
    

    Wenn jetzt die 1.Datei vor der 2. kompeliert wird, sind die ganzen Funktionen und Variablen nicht definiert


  • Mod

    Na und? Das Linken geschieht später, dann wenn alles bereits compiliert ist.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x) in das Forum Compiler- und IDE-Forum verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Nur so nebenbei: Den Vorgang nennt man "Kompilierung".



  • Der spuckt noch vor dem Linken die Fehler aus



  • Achso, das meinst du - dafür gibt es eine recht einfache Lösung: du schreibst deine Include-Anweisungen so, daß jeder die von ihm verwendeten Deklarationen erhält.



  • Also das ich bei ieInitWindow.h #include "IEngine.h" schreibe? Oder wie ist das gemeint?



  • Ja, und umgekehrt sind die #include's am Ende der IEngine.h vermutlich unnötig.



  • Dann kommen aber diese Fehler:

    1>Verknüpfen...
    1>IEngine.obj : error LNK2005: "__int64 ie_g_llFrequency" (?ie_g_llFrequency@@3_JA) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "int ie_g_bExitCalled" (?ie_g_bExitCalled@@3HA) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "int ie_g_bActivated" (?ie_g_bActivated@@3HA) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "double ie_g_dFrequency" (?ie_g_dFrequency@@3NA) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "double ie_g_dTime" (?ie_g_dTime@@3NA) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "struct HWND__ * ie_g_hWnd" (?ie_g_hWnd@@3PAUHWND__@@A) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "double ie_g_dNumSecsPassed" (?ie_g_dNumSecsPassed@@3NA) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "int ie_g_bInitCalled" (?ie_g_bInitCalled@@3HA) ist bereits in ieInitWindow.obj definiert.
    


  • Das sind alles Veriablen, die ich in IEngine.h definiert habe.



  • In einem Header definiert man ja auch keine Variablen - dort solltest du bestenfalls extern-Deklarationen verwenden (und deinem Projekt eine IEngine.cpp mit den Definitionen hinzufügen).



  • Das ist IEngine.h:

    //IEngine.h
    //Funktion:	Headerdatei der Engine	
    #pragma once
    
    #include <Windows.h>
    ...
    
    //Globale Variablen
     BOOL		ie_g_bInitCalled;		// Wurde die Engine initialisiert?
     BOOL		ie_g_bExitCalled;		// Wurde die Engine heruntergefahren?
     LONGLONG	ie_g_llFrequency;		// Frequenz des Zeitgebers
     double		ie_g_dFrequency;		// Frequenz des Zeitgebers (double)
     double		ie_g_dTime;				// Zeitzähler
     double		ie_g_dNumSecsPassed;	// Vergangene Sekunden seit letztem Frame
     BOOL		ie_g_bActivated;		// Ist das Fenster aktiv?
    ...
    
    //Rückgabewerte
    enum ieResult
    {
    	IE_OK			=	0,
    	IE_ERROR		=	1,
    	IE_CANCELED		=	2,
    	IE_NOT_FOUND	=	3,
    	IE_STOP			=	4,
    };
    
    //Die einzelnen Bestandteile hinzufügen
    #include "ieInitWindow.h"
    #include "ieVector3.h"
    #include "ieMatrix.h"
    ...
    

    Was habe ich jetzt falsch gemacht?



  • Dieser Header wird von mehreren Übersetzungseinheiten verwendet - da bekommt jede eine Kopie der definierten Variablen (und der Linker reagiert mit dem obengenannten Fehler). Das Zauberwort hier heißt "extern":

    //IEngine.h
    ...
    extern BOOL        ie_g_bInitCalled;        // Wurde die Engine initialisiert?
    ...
    
    //IEngine.cpp
    #include "IEngine.h"
    
    BOOL        ie_g_bInitCalled;        // Wurde die Engine initialisiert?
    ...
    


  • Bau mal Codeguards in deine Header.

    Header am Ende nicht gut, hat man schon geschrieben 😕

    MfG f.-th.



  • Vielen Dank! es klappt wieder! 😉



  • Hatte das falsche Stichwort 😡

    Das war gemeint:
    http://de.wikibooks.org/wiki/C-Programmierung:_Eigene_Header

    MfG f.-th.



  • f.-th. schrieb:

    Bau mal Codeguards in deine Header.

    Die Tuer schrieb:

    #pragma once

    Er braucht also keine (sofern er den Code nicht durch Compiler, die diese Direktive nicht unterstützen, jagen möchte).



  • Wenn ich jetzt aber in ein anderes Projekt das Engine-Projekt hinzufüge, kommen Linker-Fehler (Verweis auf nicht aufgelöstes externes Symbol ""enum ieResult __cdecl InitWindow(int,int,char *,struct HICON__ *,struct HINSTANCE__ *)" (?InitWindow@@YA?AW4ieResult@@HHPADPAUHICON__@@PAUHINSTANCE__@@@Z)" in Funktion "_WinMain@16 ...)

    IEngine.h

    ...
    #include"ieInitWindow.h"
    

    ieInitWindow.h

    #pragma once
    #include "IEngine.h"
    
    //Funktionen
    LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    ieResult InitWindow(int iWidth, int iHeight, char* cName, HICON hIcon, HINSTANCE hInst);
    

    ieInitWindow.cpp

    #include "ieInitWindow.h"
    ieResult InitWindow(int iWidth, int iHeight, char *cName, HICON hIcon, HINSTANCE hInst)
    {
    	[Definition der Funktion]
    }
    

    Test-Projekt
    Test.cpp

    #include "..\\..\\Engine\\Engine\\IEngine.h"
    
    int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int ncmdshow)
    {
    	InitWindow(10, 10, "Name", NULL, hInst);
    	...
    
    }
    

Anmelden zum Antworten