1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

[C] Struktur deklarieren

Dieses Thema im Forum "C/C++" wurde erstellt von üäpöol, 4. Mai 2012.

  1. üäpöol

    üäpöol Erfahrenes Mitglied

    Hi,
    ich habe ein etwas unübersichtliches Projekt, bei dem ich Strukturen, Variablen und Funktionen in eine andere Datei sollen. Das bedeutet, dass ich in einer *.h die Deklarationen und in einer functions.c die Definitionen mache. Es funktioniert auch alles, bis auf die Strukturen.
    [C]
    struct xyz;
    [/C]
    funktioniert nicht: Ich bekomme haufenweise Fehlermeldungen. Weißt jemand, wie man Strukturen deklarieren kann?!
  2. ibafluss

    ibafluss Erfahrenes Mitglied

    Zeig mal, wie du das in den Headern und c-Dateien gemacht hast.
    Und welche Fehler gibt der Compiler genau?

    So wie du das hier gezeigt hast stimmt das schon.

    Lg
  3. üäpöol

    üäpöol Erfahrenes Mitglied

    Das ist die Fehlermeldung:
    Code (Text):
    1.  
    2. header.h:10: error: array type has incomplete element type
    3.  
    Zeile 10 ist
    [C]
    struct GDTstruct GDT[6];
    [/C]
    Ich benutze GCC und linke dann die verschiedenen Dateien mit LD.
  4. saftmeister

    saftmeister Nutze den Saft! Premium-User

    Die Fehlermeldung bedeutet, das struct GDTstruct noch nicht deklariert ist. Es kommt jetzt voll darauf an, was du mit der Struktur abbilden willst. Hier mal ein einfaches Beispiel:

    Code (C):
    1.  
    2. // In die Header-Datei z.B. point.h
    3. #ifndef POINTS_H
    4. #define POINTS_H
    5.  
    6. struct point {
    7.    int x;
    8.    int y;
    9.    int z;
    10. };
    11.  
    12. #endif
    13.  
    Dann im C-File:

    Code (C):
    1.  
    2. #include "point.h"
    3.  
    4. // Ein Array mit 10 Punkt-Variablen anlegen
    5. struct point points[10];
    6.  
    7. int main(int argc, char **argv)
    8. {
    9.     points[0].x = 14;
    10.     points[0].y = 25;
    11.     points[0].z = 33;
    12. }
    13.  
  5. üäpöol

    üäpöol Erfahrenes Mitglied

    OK. Danke. Es muss natürlich so aussehen. Es gibt aber noch ein anderes großes Problem: Es wird einfach nicht erkannt, dass die Variablen schon deklariert wurden:
    Code (Text):
    1.  
    2. functions.c:6: warning: data definition has no type or storage class
    3. functions.c:6: warning: type defaults to 'int' in declaration of 'vidmem'
    4. functions.c:6: error: conflicting types for 'vidmem'
    5. header.h:42: note: previous declaration of 'vidmem' was here
    6.  
    functions.c
    [C]
    vidmem = (char*) 0xB8000;
    [/C]
    header.h
    [C]
    char *vidmem;
    [/C]
    Ich verstehe's leider nicht.
  6. saftmeister

    saftmeister Nutze den Saft! Premium-User

    Hast du den include der header.h in der functions.c am Anfang der Datei gemacht oder erst weiter unten im Code?

    Mit welchem Compiler kompilierst du?
  7. üäpöol

    üäpöol Erfahrenes Mitglied

    [C]
    #include "header.h"
    [/C]
    am Anfang der Datei
  8. saftmeister

    saftmeister Nutze den Saft! Premium-User

    Also mal davon abgesehen, dass der Zeiger auf den Video-Speicher in kein Header-File rein sollte, da er nur innerhalb des Codes benutzt werden sollte, der den Video-Speicher schreibt, kann es sein, das du die Zuweisung vidmem = 0xb8000 im globalen Bereich der functions.c machst?

    Ich würde ein static char * innerhalb der functions.c anlegen und sofort mit 0xb8000 belegen.
  9. üäpöol

    üäpöol Erfahrenes Mitglied

    Aber es ist ja nicht nur diese Variable. Es ist ja so bei allen Variablen.
  10. saftmeister

    saftmeister Nutze den Saft! Premium-User

    Variablen sollten nur dort angelegt werden, wie sie wirklich gebraucht werden. Prototypen, Strukturen und Defines können in Header-Files abgelegt werden. Variablen sollten das nicht. Sie gehören dort nicht hin. Und es kann wie bei deinem Beispiel zu seltsamen Randwirkungen kommen. Wenn du eine Variable oder den Wert der Variablen in einem anderen .c-File benötigst, erstell ein extern oder noch besser einen Getter.
  11. sheel

    sheel Mod # I love Asm Moderator

    Genau.

    Also
    x.h
    Code (C++):
    1.  
    2. extern char *vidmem;
    3.  
    und in einer .cpp
    Code (C++):
    1.  
    2. char *vidmem;
    3.  
    Verwendet werden kann es jetzt in jeder Datei, die die x.h einbindet
  12. üäpöol

    üäpöol Erfahrenes Mitglied

    Ich bekomme jetzt keine Fehlermeldungen mehr, nur ein paar Warnungen.
    Code (Text):
    1.  
    2. kernel\/header.h:10: warning: useless storage class specifier in empty declaration
    3.  
    In dieser Zeile steht:
    [C]
    } __attribute__((packed));
    [/C]
    Das ist das Ende einer Struktur. Das Ganze soll ja ein kleines OS werden, nur leider hängt es einfach. Ich vermute, dass es an den Warnungen liegt, weil die Struktur gepackt sein muss.

    EDIT:
    Ich habe das packed jetzt mal weggelassen. Das ändert auch nichts. Es hat also damit nichts zu tun.

    EDIT2:
    [C]
    extern struct GDTstruct
    {
    // ...
    } __attribute__((packed));
    [/C]
    so sieht du Struktur aus.

    EDIT3:
    Sorry, für die vielen EDITs. Ich habe das extern jetzt mal weggelassen und bekomme keine Warnungen mehr. Das OS hängt aber trotzdem.
    main.c
    [C]
    #include "header.h"
    // ...
    int main() {
    start_install();
    // ...
    }
    [/C]

    header.h
    [C]
    struct GDTstruct
    {
    // ...
    } __attribute__((packed));
    // ...
    extern void start_install();
    [/C]

    functions.c
    [C]
    struct GDTstruct
    {
    // ...
    } __attribute__((packed));
    // ...
    void start_install();
    // ...
    void start_install() {
    // ...
    }
    [/C]
    Ich weiß leider nicht, was ich falsch mache. :(
    Zuletzt bearbeitet: 5. Mai 2012
  13. saftmeister

    saftmeister Nutze den Saft! Premium-User

    Was heißt, das OS hängt? Hast du "nur" die Global Descriptor Table eingebaut? Die wird keine spürbaren Änderungen bewirken, das ist nur die Vorbereitung, um die IDT implementieren zu können. Wo hast du die Infos her, wie man ein OS aufbaut? Liest du LowLevel? Wenn ja, warum baust du dann nur den Code und liest nicht die ganzen Artikel zu den Themen?
  14. üäpöol

    üäpöol Erfahrenes Mitglied

    Nein. Bisher hatte das OS einen Countdown, hat auf eine Taste gewartet und dann rebootet. Ich benutze übrigens GRUB, aber nachdem das OS von GRUB geladen wurde passiert nichts. Es hängt so, als ob ich
    [C]
    while(1);
    [/C]
    geschrieben hätte. Ich kann leider nichts überprüfen, da selbst die einfachste Textausgabe nichts bewirkt.
  15. saftmeister

    saftmeister Nutze den Saft! Premium-User

    Mit welchem EMU testest du?
  16. üäpöol

    üäpöol Erfahrenes Mitglied

    VirtualBox; Bochs startet einfach gleich neu.
  17. saftmeister

    saftmeister Nutze den Saft! Premium-User

    Nimm Bochs :)

    Und zwar aus einem Grund: An Bochs kann man GDB dran hängen und damit debuggen. Außerdem kann man Bochs so konfigurieren, das er nicht neu startet - wenn ich mich richtig erinnere (ist schon ne Weile her, dass ich mich mit dem Thema beschäftigt habe).

    Läuft der Kernel denn, wenn du die Initialisierung der GDT - also den Funktionsaufruf - wieder raus nimmst? Wenn ja, dann zeig mal den kompletten Code für die GDT. Da bauen Neulinge (auch wie ich damals) gern Fehler ein - ist ein bisschen tricky das Thema.
  18. üäpöol

    üäpöol Erfahrenes Mitglied

    Klar, mach ich natürlich, aber daran kann es doch im Prinzip nicht liegen, weil alles perfekt funktioniert, wenn ich die Strukturen, Variablen und Funktionen alle in der main.c habe und die anderen Dateien weglasse, oder?
    EDIT:
    Weiß jemand, wie automatisches Neustarten verhindert wird? Google hilft mir leider nicht. *beleidigt* :D
    EDIT2:
    Ich hab's grad mit echter Hardware versucht (meinem PC) und dort ist es das selbe wie in der VBox.
    Zuletzt bearbeitet: 5. Mai 2012
  19. saftmeister

    saftmeister Nutze den Saft! Premium-User

    Versuch mal das: Öffne die bochsrc-Datei und such nach der Zeile, die mit cpu anfängt. In der stehen Parameter, die durch Komma getrennt sind. Füge dort einen zusätzlichen Parameter reset_on_triple_fault=0 hinzu.

    Ansonsten wäre noch zu erwähnen, das Bochs loggen kann. Das solltest du verwenden. Hier ist das Manual zur bochsrc: http://bochs.sourceforge.net/doc/docbook/user/bochsrc.html

    Und: Solange du keinen Source zeigst oder sonst irgendwelche Hinweise z.B. ein Log-File kann man dir schlecht helfen.
  20. üäpöol

    üäpöol Erfahrenes Mitglied

    Ich hab's jetzt so gestartet und bekomme folgende Fehlermeldung:
    Code (Text):
    1.  
    2. exception(): 3rd (13) exception with no resolution
    3.  
    Aber nochmal die Frage: Kann es am normalern Code liegen?! Es funktioniert wie gesagt alles perfekt, wenn die Funktionen, Variablen und Strukturen in der main.c deklariere und definiere. Ich habe ja nur versucht, Teile der Datei auszulagern, um mehr Übersichtlichkeit zu haben. Und erst jetzt gibt es das Problem, das der Kernel "hängt". Denn imho muss es doch daran liegen, dass ich die Strukturen, Variablen und Funktionen falsch in die andere Datei ausgelagert habe, oder?
    EDIT:
    Nachdem ich auf Continue gedrückt habe, kommt noch diese Fehlermeldung:
    Code (Text):
    1.  
    2. Entering to shutdown state still not implemented
    3.  
    Vielleicht hilft das ja. :)

Diese Seite empfehlen