LNK2005, alles richtig gemacht? Include Problem?



  • Hallo,

    beim Linken kommt immer der LNK2005 Fehler. Bin eigentlich der Meinung das alles OK sein müsste. Vielleicht koennt Ihr mal einen Blick drauf werfen.

    Vielen Dank

    // kalender.c
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "typen.h"
    #include "funktionen.h"
    
    // typen.h
    #ifndef TYPEN_H
    #define TYPEN_H
    
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    #include <string.h>
    ...
    #endif
    
    // funktionen.h
    #ifndef FUNKTIONEN_H
    #define FUNKTIONEN_H
    #include "typen.h"
    ...
    #endif
    
    // funktionen.c
    
    #include "funktionen.h"
    


  • VC Hilfe schrieb:

    A header file declared and defined a variable. Possible solutions include:

    Declare the variable in .h: extern BOOL MyBool; and then assign to it in a .c or .cpp file: BOOL MyBool = FALSE;
    ...

    Brauchst Du die "typen.h" in "funktionen.h" wirklich?
    Sonst zeig mal mehr Code, bitte.



  • naja, was heißt brauchen, aber der übersichtlichkeit halber, wollte ich es strukturieren:
    LNK - Fehler bei :
    alender.obj : error LNK2005: _pRun already defined in functionen.obj
    kalender.obj : error LNK2005: _pOld already defined in functionen.obj
    kalender.obj : error LNK2005: _pNew already defined in functionen.obj
    kalender.obj : error LNK2005: _pfirst already defined in functionen.obj
    kalender.obj : error LNK2005: _pHead already defined in functionen.obj
    Mehr Kot:

    // kalender.c
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "typen.h"
    #include "funktionen.h"
    int main() {
    //noch leer
    }
    
    //typen.h
    
    #ifndef TYPEN_H
    #define TYPEN_H
    
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAXCHARS 200
    #define MAXDATECHARS 10
    #define MAXTIMECHARS 5
    
    #define TRUE 1
    #define FALSE 0
    #define DATEI test.dat
    
    struct datum_ {
    
    	short int min;
    	short int hours;
    	short int day;
    	short int month;
    	short int year;
    
    };
    
    typedef struct datum_ Datum;
    
    struct kalender_ {
    
    	char Text[MAXCHARS];
    	Datum datum;
    	struct kalender_ * Next;
    //	kalender_ * next;
    };
    
    typedef struct kalender_ Kalender;
    
    // Zeiger für die verkettete Liste
    Kalender *pHead = NULL;								
    Kalender *pfirst = NULL;
    Kalender *pNew = NULL;
    Kalender *pOld = NULL;
    Kalender *pRun = NULL;
    
    #endif
    
    #include "funktionen.h"
    
    // Auswahl abfragen
    //-----------------------------------------------------------
    void selectTask(char auswahl) {
    //	char text[MAXCHARS];
    
    	if(auswahl == 1) {
    //		printf("\nText:");
    //		scanf("%s",text);
    //		printf("Zeit:");
    		//TimeToStruct
    //		scanf("%s",zeit);
    
    //		scanf("%s",datum);
    
    //		newDate(text,zeit,datum);
    
    	}
    	else if(auswahl == 2) {
    		printCalender();
    	}
    }
    
    // Ausgabe Menu
    //-----------------------------------------------------------
    void printMenu(void) {
    	printf("Bitte treffen Sie eine Auswahl\n");
    	printf("1) neuen Termin einlesen	 \t 2) Termine anzeigen\n");
    	printf("3) Kalender neu laden		 \t 4) gesamten Kalender loeschen\n");
    	printf("5) einzelnen Termin loeschen \t\t 6) speichern und exit\n");
    	printf("Auswahl:");
    }
    
    // neuen Termin anlegen
    //-----------------------------------------------------------
    void newDate(char * text,Datum * datum){
    	//
    	pOld = pNew;
    	pNew=(Kalender*)calloc(1,sizeof(Kalender));
    	copyDate(&pNew->datum,datum);
    	strcpy(pNew->Text,text);
    	pNew->Next = NULL;
    
    	if(pHead!=NULL) 
    		pOld->Next = pNew;
    	else 
    		pHead = pNew;
    
    };
    // Kalender ausgeben
    //-----------------------------------------------------------
    void printCalender(void) {
    
    	int n = 1;
    	sortCalender();
    	pRun = pHead;
    	while (pRun != NULL) {
    		printf("Termin %i:%i.%i.%i,%i:%i...%s\n",n++,pRun->datum.day,pRun->datum.month,pRun->datum.year,pRun->datum.hours,pRun->datum.min,pRun->Text);
    		pRun=pRun->Next;
    	}
    }
    // Kalender sortieren
    //-----------------------------------------------------------
    void sortCalender(void) {
    
    	int year1 = 0;
    	int year2 = 0;
    	int month1 = 0;
    	int month2 = 0;
    	int day1 = 0;
    	int day2 = 0;
    	int h1 = 0;
    	int h2 = 0;
    	int min1 = 0;
    	int min2 = 0;
    
    	pRun = pHead;
    	while (pRun != NULL) {
    		if (pRun->Next != NULL) {
    
    			if (year1 == year2) {
    				if (month1 == month2) {
    					if (day1 == day2) {
    						if (h1 == h2) {
    							if (min1 == min2) {
    
    							}
    							else if (min1>min2) {
    //								swap(pRun,pRun->Next);
    							}
    						}
    						else if (h1>h2) {
    			//				swap(pRun,pRun->Next);
    						}
    					}
    					else if (day1 > day2) {
    			//			swap(pRun,pRun->Next);
    					}
    
    				}
    				else if (month1 > month2) {
    		//			swap(pRun,pRun->Next);
    				}
    			}
    			else if (year1 > year2) {
    		//		swap(pRun,pRun->Next);
    			}
    		}
    		pRun = pRun->Next;
    	}
    }
    
    // Datum kopieren
    //-----------------------------------------------------------
    void copyDate(Datum * date1, Datum * date2) {
    	date1->year = date2->year;
    	date1->month = date2->month;
    	date1->day = date2->day;
    	date1->hours = date2->hours;
    	date1->min = date2->min;
    
    }
    
    void TimeToStruct(char * s, Datum * datum) {
    
    	datum->hours = 0;
    	datum->hours += (s[0]-48)*10;
    	datum->hours += (s[1]-48);
    
    }
    
    // funktionen.h
    #ifndef FUNKTIONEN_H
    #define FUNKTIONEN_H
    #include "typen.h"
    
    void selectTask(char);
    void newDate(char *, Datum * );							// neuen Termin anlegen
    void saveCalendar(void);								// Kalender speichern
    void loadCalendar(void);								// Kalender laden
    void deleteCalendar(void);								// Kalender löschen
    void printCalender(void);								// Kalender ausgeben
    void sortCalender(void);								// Kalender sortieren
    void deleteDate(void);									// Termin löschen
    void printMenu(void);									// Menu anzeigen
    //void swap(Kalender *, Kalender *);
    void copyDate(Datum *, Datum *);
    void TimeToStruct(char *,Datum *);
    
    #endif
    


  • Hab jetzt noch nicht den Überblick aber in der funktionen.h brauchst Du typen.h nicht, eine Vorabdeklaration reicht aus, wenn Du nur Zeiger benutzt. Includen kannste dann in der .c Datei.

    // funktionen.h
    #ifndef FUNKTIONEN_H
    #define FUNKTIONEN_H
    
    struct kalender;
    
    void selectTask(char);
    void newDate(char *, Datum * );							// neuen Termin anlegen
    void saveCalendar(void);								// Kalender speichern
    void loadCalendar(void);								// Kalender laden
    void deleteCalendar(void);								// Kalender löschen
    void printCalender(void);								// Kalender ausgeben
    void sortCalender(void);								// Kalender sortieren
    void deleteDate(void);									// Termin löschen
    void printMenu(void);									// Menu anzeigen
    //void swap(Kalender *, Kalender *);
    void copyDate(Datum *, Datum *);
    void TimeToStruct(char *,Datum *);
    
    #endif
    


  • ja das würde gehen, aber leider noch keine Lösung, ich warte gespannt



  • hat denn keiner eine Lösung für mein Problem? Vielleicht könnt Ihr einfach mal meinen Code bei Visual übernehmen? Zickt er dann auch rum?

    Bei alten Projekten von mir ging es ja auch. Ich habe mich schon gefragt, ob irgendwelche Linker oder Compilereinstellungen verändert wurden

    Viele Grüße

    Filip



  • Ja was läuft wohl schief? Die Fehlermeldungen sagen es bereits...

    pRun beispielsweise wurde in "typen.h" definiert. Wenn typen.h mehrmals eingebunden wird (was hier zweifelsohne der Fall ist - einmal in "kalender.c" und ein weiteres Mal in "funktionen.c"), funktioniert das Kompilieren selbstverständlich, denn pro kompilierter Datei wurde "typen.h" nur einmal eingebunden. Werden dann aber vom Linker alle .obj-Files zusammengebunden, kommen aus den einzelnen Objektdateien mehrere Einbindungen von "typen.h", was zur Folge hat, dass pRun mehrfach definiert wird (-> darum auch ein Linker- und kein Compilerfehler).

    Um das Problem zu beheben, müssen pRun und ähnliche in eine "typen.c" geschrieben werden und in "typen.h" als extern vermerkt werden. Dann sollte es gehen.



  • proggaholic schrieb:

    Wenn typen.h mehrmals eingebunden wird (was hier zweifelsohne der Fall ist - einmal in "kalender.c" und ein weiteres Mal in "funktionen.c"), funktioniert das Kompilieren selbstverständlich...

    Aber ich denke #ifndef verhindert ein doppeltes Einbinden?

    MfG Filip



  • Äh...

    Ja klar, natürlich. Hab nicht genau genug hingesehen. Allerdings sind Definitionen in header-files eigentlich nicht erlaubt...



  • also.... es funktioniert, danke an alle die geholfen haben. Aber wieso vielleicht kann mir trotzdem noch einer erklären, warum #ifndef nicht vor doppelter definition schützt?



  • Hat das Auslagern in .c geholfen?

    Falls ja, liegt es daran, dass #ifndef eine Präprozessordirektive ist. Der Präprozessor wird beim Kompilieren als allererstes aufgerufen (noch vor Compiler/Linker/Debugger). Dadurch wird lediglich verhindert, dass "typen.h" mehrmals in "kalender.c" und "funktionen.h" eingebunden wird (d.h. man kann zwar mehrmals #include machen, aber alle ausser dem ersten werden ignoriert). Wenn dann der Linker dran ist, wurde der include-Guard ( #ifndef ) bereits abgearbeitet, und stellt plötzlich fest, dass die Definitionen doppelt vorkommen. D.h. der include-Guard hat seine Arbeit schon längst getan, sodass er beim Linken nicht mehr greift und dadurch doppelte Definitionen Fehler werfen (was in gewisser Weise ja auch gut so ist).


Anmelden zum Antworten