wie kann ich eine Konstante Global definieren, die in mehreren Quelldateien verwendet wird? Follgendes Problem: ich habe ein Projekt, das vorher aus einer Quelldatei (main.c) bestand, in der alle anderen Sourcedateien per #include hineingezogen wurden. In der makefile war auch nur SCR=main.c definiert. Damit ich aber in allen Dateien simulieren kann sollen alle Quelldateien in der makefile angegeben werden. Mittlerweile habe ich das auch geschaft, auch die #includes gelöst, und könnte kompilieren. Das Problem steht aber noch bei 5 Konstanten. Definiere ich sie in der Projekt-Header Datei (per include in allenQuelldateien) mäkelt der linker die mehrfachen definitionen. Makrodefinition wie #ifndef funktionieren scheinbar nich. Definiere ich die Konstanten nur in der main.c fehlt sie in den anderen Dateien komplett. Wie kann man das umgehen, wie wird das richtig gelöst? Es gibt zur Include-Story zwar viele Informationen, aber ich habe leider niemanden gefunden der mein Problem hatte, bzw. was mir hilft.
Ich glaube das geht so: extern unsigned char variable; Einfach mal ausprobieren! Dirk.
Er wollte eine Konstante definieren, keine Variable. Die belegt ausserdem Speicher. Mit #ifdef geht das sehr wohl. Am besten inkludierst Du die Header-Datei, in der Deine Konstanten stehen, von allen Dateien und fragst per #ifdef ab, ob die Header-Datei schon inkludiert wurde. So macht man das immer.
kannst du mir ein beispiel geben? ich habe schon ne menge ausprobiert, aber die (für mich logischte) variante: #ifndef incl #include "netzwerk.h" #endif funktioniert nicht. in der netzwerk.h (meine headerdatei, die die Definitionen und Konstanten für das Projekt enhält habe ich ausserdem #define incl eingefügt.
Ist zwar etwas umständlich, funktioniert aber. Schau Dir mal die standard Includes an, wie es dort gemacht wird. Wenn aber erst der Linker meckert, dann sind es keine Konstanten, sondern Funktionen oder Variablen. Peter
@Henning: >#ifndef incl >#include "netzwerk.h" >#endif Ist schon fast richtig. Aber da beim nächsten Inkludieren das Flag 'incl' immer noch nicht definiert ist, wird der Kompiler "netzwerk.h" wieder inkludieren. Also mußt Du 'incl' beim ersten Mal definieren. Das geht dann so: #ifndef incl #define incl #include "netzwerk.h" #endif Am besten benennst Du das Flag auch noch passend, also z.B. NETZWERK_H_INCL (oder so). Wie Peter schon geschrieben hat, schau Dir mal die standard Includes an. Joline
ich habe weiter probiert, aber das kompilieren klappt immernoch nicht bis zum ende fehlerfrei. die Fehler tauchen erst beim Linker auf, er bemängelt alle Dateien, bei denen das netzwerk.h includiert ist. Die Fehlermeldungen lauten -- device.o(.bss+0x0): In function `WriteRTL': d:\elektronik\avr\projekte\netzwerk/device.c:31: multiple definition of `TCP_Socket_Status' main.o(.bss+0x0):d:\elektronik\avr\projekte\netzwerk/main.c:78: first defined here -- wobei die Zeilenangabe leider müll ist, es sind zwar unterscheidliche zeilennummern gemeldet, die haben aber nichts mit dem Problem zu tuen (wie mir scheint). Die Zeilen die den linker wohl wirklich stören sind: -- (aus netzwerk.h) const int mymac[6] = {0x00,0x20,0x18,0xb1,0x04,0xa2}; const int MYIP[4] = {192,168,2,99}; unsigned char Sendpage = 2; unsigned int TCP_Socket_Store[10] = {0,0,0,0,0,0,0,0,0,0}; unsigned int TCP_Socket_Status[10] = {0,0,0,0,0,0,0,0,0,0}; -- mit 2 anderen zeile hat er kein Problem: -- unsigned long Seq_counter; unsigned long Ack_counter; -- auffällig ist, das ihm die Zeilen mit Zuweisung stören. Wenn es richtig ist, das die Arrays automatisch auf 0 definiert sind kann man die zuweisung ja entfernen -> schon gehen die beide Zeilen OK. Das könnte ich ja nun bei allen Zeilen machen und in der init() die werte manuell setzen. was allerdings optisch nicht das schönste ist. Wie kann man das umgehen Wenns nicht ander Art des Include liegen kann könnt ihr das überspringen: Nur um nicht aneinander vorbei zu reden: wenn ihr mit standard includes zB stdio.h mein, die hab ich mal untersucht -> ich habe jetz in der netzwerk.h ganz am anfang die #ifndef und #define Anweisung eingefügt und ganz am Dateiende die #endif. bei allen anderen Dateien wird die datei normal per #include eingefügt.
ich habe die manuelle Wertzuweisung mal ausprobiert und konnte nun komplett compilieren, linken und was noch so dazugehört. Aber programmtechnisch ist die Sache nicht schön... Hab ihr eine Idee?
Die Geschichte mit #ifndef etc. verhindert nur, dass bei einem Kompiliervorgang eine Datei mehrfach included wird. Alle .c-Dateien deines Projekts werden ja einzeln kompiliert, daher stört sich der Compiler erstmal nicht daran. Da in jedem object file, was die netzwerk.h included hat das Symbol "TCP_Socket_Store" exportiert ist, hat der Linker was dagegen, da du damit eigentlich eine Variable meinst, die jetzt aber in allen .c-Files vorhanden ist. Die Lösung des Problems ist folgende: Du verschiebst die Zeilen in eine .c-Datei, am besten dahin, wo soe funktionell am besten hinpassen, also dahin, wo du deine Netzwerk-Funktionen auch hast. Somit wird nach dem Kompilieren aller dateien das Symbol "TCP_Socket_Store" nur in DIESER Datei exportiert. Damit aber alle anderen source-Files wissen, dass es irgendwo da draussen eine Variable "TCP_Socket_Store" gibt, musst du entweder in jeder .c-Datei einzeln "extern unsigned char TCP_Socket_Store[10];" reinschreiben, oder (was eleganter ist) eben in die netzwerk.h schreiben. Jetzt hast du folgende Situation: netzwerk.c: definiert die Variable x.c \ y.c > wissen durch das "extern", dass es die variable woanders gibt z.c /
Ich habe die Variablen und Konstanten nun mit extern eingebungen. @Christoph Krüger: Danke, das ist genau der Tip gewesen, der mir gefehlt hat! Danke auch an die anderen!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.