hallo
ich binde die datei test.c mit #include "test.c" ein. nun wenn ich in
dieser datei irgendein c code schreibe ausser #define dann gibt der
compiler fehler aus.
ein beispiel:
uint8_t var_1;
../test.c:1: error: expected '=', ',', ';', 'asm' or '__attribute__'
before 'var_1'
ich vermute dass bei compiler zusätzlich was eingestellt werden muss
dass die include datei "ganz normal" eingegunden wird.
meine prog. umgebung: xp, avrstudio 4.16, winavr 20081205
gruss
Weil der Compiler uint8_t nicht als Datentyp kennt, denkt er Du möchtest
einen Wert zuweisen. Vermutlich hast Du einfach das #include <..> für
das .h-File vergessen, in dem der Typ uint8_t definiert ist.
Du solltest übrigens keine *.c Files per Include einbinden. Include ist
für *.h Files. Wenn Du mehrere *.c Files brauchst, dann kannst Du die
einzeln kompilieren und dann beim Linken alle *.o Files angeben oder Du
gibst dem Compiler gleich eine Liste der *.c Files die er zu einem
Executable machen soll. Schau Dir einfach mal ein x-beliebiges Makefile
an, da kann man sehen wie das gemacht wird.
Man kann mit #include alles includen. Egal ob .h, .c, .txt, .schnitzel
oder sonstwas. Der Praeprozessor fuegt den Teil einfach ein, basta - nur
syntaktisch korrekt muss das Resultat sein.
Um Rolfs Problem zu loesen, muesste er schon ein wenig mehr zeigen.
Mindestens das File das den include macht und das komplette test.c.
Man kann mit #include alles includen. Egal ob .h, .c, .txt, .schnitzel
oder sonstwas. Der Praeprozessor fuegt den Teil einfach ein, basta - nur
syntaktisch korrekt muss das Resultat sein.
@ Peter Stegemann
das habe ich auch gemeint. mehr möchte ich auch nicht. in meiner
referenz steht auch "Der Präprozessor entfernt die #include-Zeile und
ersetzt sie durch den gesamten Quelltext der Include-Datei. Die
Quelltextdatei selbst wird nicht physisch verändert, der Compiler erhält
jedoch den modifizierten Text zur Übersetzung. "
dem scheint es aber nicht so zu sein...
hier ist gleich makefile
########################################################################
#######
# Makefile for the project projekt_1
########################################################################
#######
## General Flags
PROJECT = projekt_1
MCU = atmega644p
TARGET = projekt_1.elf
CC = avr-gcc
## Options common to compile, link and assembly rules
COMMON = -mmcu=$(MCU)
## Compile options common for all C compilation units.
CFLAGS = $(COMMON)
CFLAGS += -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char
-funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d
## Assembly specific flags
ASMFLAGS = $(COMMON)
ASMFLAGS += $(CFLAGS)
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS += -SRC=$(TARGET).c-globals.c -Wl,-Map=projekt_1.map
## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings
## Objects that must be built in order to link
OBJECTS = projekt_1.o globals.o
## Objects explicitly added by the user
LINKONLYOBJECTS =
## Build
all: $(TARGET) projekt_1.hex projekt_1.eep projekt_1.lss size
## Compile
projekt_1.o: ../projekt_1.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<
globals.o: ../globals.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<
##Link
$(TARGET): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o
$(TARGET)
%.hex: $(TARGET)
avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@
%.eep: $(TARGET)
-avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
%.lss: $(TARGET)
avr-objdump -h -S $< > $@
size: ${TARGET}
@echo
@avr-size -C --mcu=${MCU} ${TARGET}
## Clean target
.PHONY: clean
clean:
-rm -rf $(OBJECTS) projekt_1.elf dep/* projekt_1.hex projekt_1.eep
projekt_1.lss projekt_1.map
## Other dependencies
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)
Um es mal zu präzisieren:
Die übliche Vorgehensweise, um syntaktische Probleme zu vermeiden, ist
das erstellen einer Headerdatei (*.h) zu jeder .c-Datei, in der sich
ausschließlich Deklarationen (jedoch keine Definitionen ) aller
Objekte befinden, die in der dazugehörigen .c-Datei definiert sind und
die für andere Module (andere .c-Dateien) sichtbar sein sollen. Und nur
die .h-Dateien werden dann mit #include eingebunden.
Außer Variablen-/Funktionsdeklarationen können in Headerdateien auch
Typdfinitionen (typedef) und Präprozessormakros stehen. Das war es dann
aber auch schon fast...
Normalerweise bindet man Quelldateien tatsächlich nicht mit #include
ein. Klar, man kann alles einbinden, aber nur in wenigen Fällen macht
das Sinn.
Sag mal, geht's noch? Du sollst den Quellcode posten und nicht
irgendwelche unsinnigen Screenshots! Das Dateiformat für C-Code heißt
nicht .jpg, sondern .c!
stell die linker Optionen wieder zurück, das macht avrstudio schon von
alleine
siehe unten die Ausgabe des Compilers...
Er versucht die globals.c zum compiliern, was natürlich fehlschlägt...
Jede .c braucht alle includes die sie selber brauch.
Such mal nach globlane Variablen hier im Forum, da wird dir geholfen...
Rolf Riller wrote:
> @ Peter Stegemann> dem scheint es aber nicht so zu sein...
Doch doch, dein projekt_1.c uebersetzt auch einwandfrei. Nur hast du
globals.c nochmal separat im Projekt - und das File alleine kann der
Compiler so nicht uebersetzen. Und selbst wenn er koennte, du haettest
den Inhalt dann doppelt, was beim Linken wieder krachen duerfte, weil du
so doppelte Symbole bekommst. Ach das liesse sich loesen, fuehrt aber
hier wohl zu weit...
Man kann zwar mit #include machen was man moechte, wenn man aber nicht
genau weiss, was man tut, haelt man sich besser an die von Johannes
beschriebenen Konventionen ;-)
Ich denke was du willst ist ein globals.c, das selbstaendig uebersetzt
(also alle noetigen includes machen!) und ein globals.h, dass die
Variablen extern deklariert und von den anderen Dateien eingebunden
wird. Wie ....... schon schrieb, muss das mehrfach hier im Forum
beschrieben sein.
Und nein, das hat nichts mit Compiler oder Linker-Einstellungen zu tun.
Mein Tip ist übrigens, dass dir ein
#include <inttypes.h>
an irgendeiner Stelle fehlt.
also ich kriegs nicht auf die reihe.
kann mir jemand ein tutoriallink geben wo erklärt wird wie man diese
problematik bewerkstelligt:
--- hauptfile.c -----
int main()
{
var_1 = 1;
var_2 = 1;
func_1();
func_2();
}
--- module_1.c ------
int var_1;
void func_1()
{
var_2 = 1;
func_2();
}
--- module_2.c -------
int var_2;
void func_2()
{
var_1 = 1;
func_1();
}
was ich möchte ist dass man "kreuz und querz" aufrufe tätigen kann, wie
man das von php oder vb.net kennt. dort includet man das nötige modul
mit seinen funktionen und variablen und gut ist es. meine hausaufgaben
habe ich schon gemacht nämlich sämtliche foren durchsucht usw. da wird
zwar viel geredet aber nichts konkretes.
danke im voraus
zunächst mal überlegst du dir, welche Informationen für module_1.c bzw.
module_2.c 'nach aussen' sichtbar sein sollen.
Für module_1.c sind das
* Es gibt eine Variable var_1
* Es gibt eine Funktion func_1
Für module_2.c sind das
* Es gibt eine Variable var_2
* Es gibt eine Funktion func_2
Dann legst du dir für jedes der beiden *.c Files ein entsprechendes
Header File an. Sinnvollerweise nennt man das Header File gleich wie das
zugehörige *.c File, nur kriegt es die Endung *.h
In diese Header Files kommen die Deklarationen für alle Dinge, die vom
*.c File exportiert werden, also von aussen sichtbar sein sollen
In deinem Beispiel sind das
--- module_1.h ------
1
externintvar_1;
2
3
voidfunc_1();
und
--- module_2.h -------
1
externintvar_2;
2
voidfunc_2();
Wie werden sie jetzt verwendet?
Ganz einfach.
Jedes *.c, dass eine Funktionalität aus einem anderen *.c benutzen will,
includiert das entsprechende Header File. Sinnvollerweise wird das
definierende C-File auch sein eigenes Header File includieren. Damit
ermöglicht man dem Compiler eine gewisse Prüfung, ob beides auch
zusammenstimmt und wenn man eigene Datentypen definiert (Strukture,
Unions) führt sowieso an diesem Include kein Weg vorbei
Konkret:
--- hauptfile.c -----
1
#include"module_1.h" // stellt var_1 und func_1 bereit
2
#include"module_2.h" // stellt var_2 und func_2 bereit
3
4
intmain()
5
{
6
var_1=1;
7
var_2=1;
8
func_1();
9
func_2();
10
}
--- module_1.c ------
1
#include"module_1.h"
2
3
intvar_1;
4
voidfunc_1()
5
{
6
var_2=1;
7
func_2();
8
}
--- module_2.c -------
1
#include"module_2.h"
2
#include"module_1.h" // weil ja var_1 und func_1 benutzt werden sollen
Hier wird auf Dinge zugegriffen, die im Modul2 definiert sind. Also muss
auch --wie ich es weiter oben schon gezeigt habe-- auch module_2.h
eingebunden werden.
Pedanterie:
s/dass/das/
Rufus t. Firefly wrote:
> Das funktioniert so nicht:> Hier wird auf Dinge zugegriffen, die im Modul2 definiert sind.
Oops. Hab ich übersehen.
Danke für den Fix.