Forum: Mikrocontroller und Digitale Elektronik Struct als extern deklarieren


von Timo P (Gast)


Lesenswert?

Hallo!

Der extern Befehl ist mir normalerweise bekannt. Aber mit einem struct 
scheint es per gcc(WINAVR) nicht zu funktionieren?!?

Habt ihr Erfahrungen?

main.c:
volatile struct bit
{
  unsigned trigger:1;
  unsigned state_1:1;
  unsigned state_2:1;
  unsigned open_signal:1;
  unsigned http:1;
}flag;


externes modul:

extern volatile bit flag;

so funktioniert es nicht. Ich weiß hier nicht, was ich falsch mache. 
Eigentlich hatte das Strukt den Namen "bit" nicht. Diesen habe ich 
vergeben, damit ich weiß, was ich als extern deklarieren muss.

von Karl H. (kbuchegg)


Lesenswert?

Timo P schrieb:

> externes modul:
>
> extern volatile bit flag;
>
> so funktioniert es nicht. Ich weiß hier nicht, was ich falsch mache.

Wenn du Compiler wärst und du nur dieses hier zur Verfügung hast

modul.c
*******
1
extern volatile bit flag;

woher weißt du, wie die Struktur aussieht, welche Member sie hat und wie 
diese Member angeordnet sind?


Jedes C-File wird für sich alleine compiliert, ohne Ansehen von anderen 
*.c File.
Wenn du daher die Struktur in einem anderem C File hast, dann ist das 
nett, hilft aber dem Modul.c nichts. Denn das hat diese 
Strukturdefinition nicht zur Verfügung.

von Klaus W. (mfgkw)


Lesenswert?

extern volatile struct bit flag;

und wie KHB bereits sagte: die Struct muß dort dann auch bekannt sein.

von Timo P (Gast)


Lesenswert?

Willst du mir jetzt sagen, dass ich das struct in dem ext. modul neu 
aufführen muss, oder willst du mir sagen, dass es nicht möglich ist?

Danke schon mal für deine Antwort!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Hier passieren zwei Dinge gleichzeitig:
1
volatile struct bit
2
{
3
  unsigned trigger:1;
4
  unsigned state_1:1;
5
  unsigned state_2:1;
6
  unsigned open_signal:1;
7
  unsigned http:1;
8
}flag;

Einerseits wird ein Strukturtyp deklariert (struct bit), andererseits 
wird eine Variable dieses Typs definiert.

Um diese Variable aus anderen Modulen heraus verwenden zu können, muss 
in anderen Modulen der Strukturtyp bekannt sein.

Daher sollten die beiden Dinge voneinander getrennt werden:
1
struct bit
2
{
3
  unsigned trigger:1;
4
  unsigned state_1:1;
5
  unsigned state_2:1;
6
  unsigned open_signal:1;
7
  unsigned http:1;
8
};
9
10
volatile struct bit flag;

Als nächster Schritt kann jetzt die Deklaration des Strukturtyps in eine 
Headerdatei ausgelagert werden, damit sie anderen Modulen bekanntgemacht 
werden kann.

In der Headerdatei steht dann folgendes:
1
struct bit
2
{
3
  unsigned trigger:1;
4
  unsigned state_1:1;
5
  unsigned state_2:1;
6
  unsigned open_signal:1;
7
  unsigned http:1;
8
};
9
10
extern volatile struct bit flag;


und im C-Sourcefile, in dem die Variable "flag" definiert wird, steht 
nur noch
1
volatile struct bit flag;

(und natürlich vorher die #include-Anweisung für die Headerdatei)

von Timo P (Gast)


Lesenswert?

Läuft jetzt!

Ist also doch problemlos möglich, auch structs als extern zu 
deklarieren.

von Timo P (Gast)


Lesenswert?

Die Idee mit dem Auslagern in die Headerfile scheint mir sehr sinvoll, 
wenn ich sowieso schon modularisiere.

Frage am Rande:

wenn ich eine main.h habe, die ich von mehreren modulen aus einbinde, 
wie kann ich verhindern, dass defines oder includes mehrfach ausgeführt 
werden?

ein
#ifdef main.h
....
#endif

funzt nicht

von Peter (Gast)


Lesenswert?

Du musst den Struct in einem Header-File definieren (als typedef) und 
dieses Header-File überall includen, wo Du diesen Struckt verwenden 
willst.

Die Structvariable kann dann in irgend einem C-File global deklariert 
werden und mittels extern in den anderen C-Files importiert werden

von Timo P (Gast)


Lesenswert?

@ Peter:

Ja, das habe ich gerade umgesetzt. Es ist auch in meine main.h 
gewandert.

Aber diese main.h includiere ich von vielen modulen aus. Evtl. ist es 
hilfreich, Vorkehrungen zu treffen, dass die includes und defines aus 
der main.h nicht mehrfach durchgeführt werden.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Timo P schrieb:
> wenn ich eine main.h habe, die ich von mehreren modulen aus einbinde,
> wie kann ich verhindern, dass defines oder includes mehrfach ausgeführt
> werden?

Sofern Du in der Headerdatei nur Dinge deklarierst, sie aber nicht 
definierst, wird da nichts "mehrfach ausgeführt".

Oder bindest Du Deine mehreren Module selbst etwa auch mit #include ein?

von !Gast (Gast)


Lesenswert?

Timo P schrieb:
> wenn ich eine main.h habe, die ich von mehreren modulen aus einbinde,
> wie kann ich verhindern, dass defines oder includes mehrfach ausgeführt
> werden?
>
> ein
> #ifdef main.h
> ....
> #endif
>
> funzt nicht
1
#ifndef __main_h__ //man beachte das 'n'!
2
#define __main_h__
3
//Code
4
#endif

Manchmal steht noch ein Wert hinter dem #define, vermutl. ich das in 
bestimmten Fällen (welchen?) nötig um einen Fehler bei der 
"Präprocessierung" zu vermeiden.

von Huch (Gast)


Lesenswert?

1
#ifndef MAIN_H
2
#define MAIN_H
3
...
4
#endif

von Johnny B. (johnnyb)


Lesenswert?

Es ist auch hilfreich, wenn Du aus dem Struct gleich einen Datentyp 
machst.
Also irgendwie so:

typedef struct
{
  unsigned trigger:1;
  unsigned state_1:1;
  unsigned state_2:1;
  unsigned open_signal:1;
  unsigned http:1;
} bit_type;

Dann kannst Du ganz normal mit dem Ding hantieren wie mit anderen Typen.

Vorwärtsdeklaraton in H Datei:
extern volatile bit_type flags;

Typ deklarieren in C Datei:
volatile bit_type flags;

Verwendung in C Datei:
flags.trigger = 1;

Sollte in etwa so funktionieren, aber habe es nicht getestet.

von Klaus W. (mfgkw)


Lesenswert?

!Gast schrieb:
> Manchmal steht noch ein Wert hinter dem #define, vermutl. ich das in
> bestimmten Fällen (welchen?) nötig um einen Fehler bei der
> "Präprocessierung" zu vermeiden.

seit Jahrzehnten überflüssig.

von !Gast (Gast)


Lesenswert?

@Klaus Wachtler
Danke für die Info!

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
Noch kein Account? Hier anmelden.