Struktur Array in Header deklarieren



  • ich möchte in einen Header File eine Struktur Array deklarieren die Länge aber erst beim initialisieren im main file definieren

    header.h:

    struct Struktur me[];
    

    main.c:

    #include header.h
    
    struct Struktur me[] =
    {
    .
    .
    .
    };
    

    das Header soll einmal wie eine Bibliothek von verschiedenen Projekten genutzt werden können ohne das man im Header was ändern muss um es dem Projekt anzupassen



  • Das ist ja schon eine Definition.

    Lass im Header das me[] weg

    Felidae_TWC schrieb:

    das Header soll einmal wie eine Bibliothek von verschiedenen Projekten genutzt werden können ohne das man im Header was ändern muss um es dem Projekt anzupassen

    So soll es ja auch sein 🙂



  • ne die Struktur habe ich schon definiert.
    das Array vom Typ Struktur muss global bekannt sein. des Länge wird aber in den Projekten Definiert.



  • im Moment sieht das so aus

    console.h

    /**
     * @file   console.h
     * @brief  UART Terminal
     * @author Joachim Jähn (joachim.jaehn@twc-zone.de)
     *
     * Eingabe von Zeichenketten über STDIO und UART. \n
     * zerlegen des Strings in Befehl und Argumente. \n
     * Aufruf einer daraus Funktion aus einem Funktionen-Vektor
     */
    
    /**
     * @brief Struktur für den Funktions-Vektor
     * @code
     * int func1(char[10][50]);
     * int func2(char[10][50]);
     * const struct func_vek_struct funk_vek[2] =
     * {
     *   {"Befehl1\0","anleitung\0",func1},
     *   {"Befehl2\0","anleitung\0",func2}
     * };
     * @endcode
     * Ein Vektor von befehlen und den dazugehörigen Funktionen \n
     * jede Funktion muss vom Typ int func(char[10][50]) sein \n
     */
    struct func_vek_struct
    {
        /** @brief Befehl der die Funktion aufruft */
        char name[10];
        /** @brief Manual des Befehls */
        char man[50];
        /** @brief Pointer auf die Funktion*/
        int (*func) (char[10][50]);
    };
    
    /**@brief Deklaration des Funktions-Vektor
     *
     * der Funktions-Vektor wird Deklaration und \n
     * kann jetzt in der main.c initialisiert werden. \n
     * man muss drauf achten die Länge des Arrays \n
     * der Anzahle der Funktionen anzupassen. \n
     * const struct func_vek_struct funk_vek[2]; \n
     *                                       ^
     * @code
     * int func1(char[10][50]);
     * int func2(char[10][50]);
     * const struct func_vek_struct funk_vek[2] =
     * {
     *   {"Befehl1\0","Anleitung\0",func1},
     *   {"Befehl2\0","Anleitung\0",func2}
     * };
     * @endcode
     */
    const struct func_vek_struct func_vek[2];
    
    /**
     * @brief Konsolen Eingabe und Befehlsinterpreter
     * @param mode
     * mode = 0 keine STDIO Umlenkung \n
     * mode = 1 STDIO Umlenkung auf UART kein Zeichen Echo \n
     * mode = 2 Zeichen Echo und Fehler Meldung \n
     * mode = 3 1 + Eingabe Aufforderung \n
     * @param func_vek[]
     * Struktur vom Format func_vek_struct \n
     * Vektor aus Befehl und dazugehöriger Funktion
     *
     * wartet auf Eingabe einer Kommandozeile und \n
     * zerlegt den String in Befehl und Argumente. \n
     * Sucht den Befehl in einem Funktionsvektor \n
     * und ruft die dazugehörige Funktion auf. \n
     * nach Ausführung der Funktion wird auf eine \n
     * neue Kommandozeile gewartet.
     */
    int console(uint8_t mode);
    

    main.c:

    ...
    const struct func_vek_struct func_vek[2] =
    {
        {"convert\0","Char --> int\0",convert},
        {"lcd\0","Etwas auf derm LCD Anzeigen.\n\t-i lcd init\0",lcd}
    
    };
    

    wenn ich jetzt zwei oder mehr Projekte habe muss ich für jedes Projekt die Array Länge Anpassen.



  • Das sieht doch ganz gut aus.

    Die \0 am Ende von Stringkonstanten kannst Du Dir übrigens sparen. Das macht C automatisch. Du erzeugst mit \0 eine zweite zusätzliche 0 am Ende der Zeichenkette, die nicht falsch aber komplett überflüssig ist.

    Du musst die Größe des Arrays auch nicht mit angeben. Das funktioniert auch so:

    const struct func_vek_struct func_vek[] =
    {
        {"convert","Char --> int",convert},
        {"lcd","Etwas auf derm LCD Anzeigen.\n\t-i lcd init",lcd}
    };
    

    Ich bin mir nur nicht sicher, ob das Argument Deines Funktionspointers nur zufällig so groß ist, wie die Stringbuffer der Struktur, oder ob Du da noch etwas falsch verstanden hast.



  • so wie es jetzt ist funktioniert es ja.
    wenn ich im Header

    const struct func_vek_struct func_vek[];
    

    schreibe und in der main des Jeweiligen Projekts

    const struct func_vek_struct func_vek[] =
    {
        {"convert","Char --> int",convert},
        {"lcd","Etwas auf derm LCD Anzeigen.\n\t-i lcd init",lcd}
    };
    

    bekomme ich die Fehlermeldung:

    ../m32/console.c|61|error: invalid application of ‘sizeof’ to incomplete type ‘const struct func_vek_struct[]’
    

    und

    ../m32/console.h|56|warning: array ‘func_vek’ assumed to have one element
    


  • Variablendefinitionen haben im Header nichts zu suchen.

    Da gehört das extern hin.

    extern const struct func_vek_struct func_vek[];
    

    Die Definition ist dann in einer .c



  • ok, im Header console.h

    extern const struct func_vek_struct func_vek[];
    

    und in der main.c

    const struct func_vek_struct func_vek[] =
    {
        {"convert","Char --> int",convert},
        {"lcd","Etwas auf derm LCD Anzeigen.\n\t-i lcd init",lcd}
    };
    

    da bekomme ich aber immer noch den Fehler:

    ../m32/console.c|61|error: invalid application of ‘sizeof’ to incomplete type ‘const struct func_vek_struct[]’
    


  • Wie sieht denn die Fehlerzeile aus (Zeile 61) ?



  • for(count1=0;count1<=sizeof(func_vek)/62;count1++)
    {
    ...
    


  • Ich bin mir nicht sicher, ob das C89 Standard ist. Wohl eher nicht, wenn der Compiler damit ein Problem hat.

    Hast Du jetzt eigentlich noch ein Problem?



  • console.c kennt die größe von func_vek nicht, da diese nicht im Header steht.
    Du kannst ein Makro nehmen und dass über die Projekteigenschaften vorgeben, oder das Abbruchkriterium ändern.

    Möglich wäre ein letzter Eintag in deiner func_vek mit nicht sinnvollen Werte:

    {"convert","Char --> int",convert}, 
    ...
      "", "", NULL}; // Kennzeichen für das Ende des Arrays
    

    Dann kannst du in console.h schreiben

    for(count1=0;func_vek[count1];count1++) 
    {
    ...
    

    Das ist eigentlich die Flexibelste Lösung.

    Was soll eigentlich die 62 da? Meinst du damit sizeof(struct func_vek_struct) ?

    Wenn du sowieso nur Stringlatere einträgst, kannst du eigentlich deine struct auch abspecken auf:

    struct func_vek_struct
    {
        char *name;
        char *man;
        int (*func) (char[10][50]);
    };
    

    Dann kann die Endekennung auch 3 mal NULL enthalten.



  • ja das Funktioniert. ich glaub damit kann ich leben danke für die Hilfe

    Was soll eigentlich die 62 da? Meinst du damit sizeof(struct func_vek_struct) ?

    ja sonst erhalte ich ja die Größe in Byte und nicht die Anzahl der Einträge.



  • Felidae_TWC schrieb:

    ja sonst erhalte ich ja die Größe in Byte und nicht die Anzahl der Einträge.

    Dann schreib beim nächsten mal auch sizeof(struct func_vek_struct) hin, wenn du das meinst.
    Das geht auch in der console.h, da die struct ja bekannt ist.
    Dafür ist sizeof ja gedacht, dass man das nicht selber ausrechnen muss.

    Was in console.c unbekannt ist, ist die Arraygröße.

    Felidae_TWC schrieb:

    ja das Funktioniert. ich glaub damit kann ich leben danke für die Hilfe

    Welche Version denn?
    Bei der Version mit den Zeigern brauchst du noch nicht einmal auf die Länge der Strings achten.



  • Die 62 hatte ich gar nicht bemerkt.

    Puh, gruselig und auch falsch:

    10 Bytes char
    + 2 Bytes allignment (eventuell zumindest)
    +50 Bytes char
    + 2 Bytes (oder 4 oder auch nicht)
    + 4 Bytes Funktionspointer oder 8 unter 64Bit?
    -----------------------------------------------
    irgendwas zwischen 64 und 88 Bytes und selbst das ist nur geraten

    Der Compiler kann in eine struct Lücken einbauen, wenn er Lust hat, und die Größe eines Zeigers ist nicht einheitlich.

    Also IMMER mit sizeof arbeiten!



  • dibada schrieb:

    Die 62 hatte ich gar nicht bemerkt.

    Puh, gruselig und auch falsch:

    10 Bytes char
    + 2 Bytes allignment (eventuell zumindest)
    +50 Bytes char
    + 2 Bytes (oder 4 oder auch nicht)
    + 4 Bytes Funktionspointer oder 8 unter 64Bit?
    -----------------------------------------------
    irgendwas zwischen 64 und 88 Bytes und selbst das ist nur geraten

    Im Code von Felidae_TWC steht etwas von UART. Daher bin ich davon ausgegangen, dass es sich um einen Mikrocontroller handelt.
    Und da wird/kann die 62 wieder stimmen.
    Zudem konnt er sich das ja auch ausrechnen, indem er sizeof(array)/Anzahl_Elemente_im_Array rechnet.

    dibada schrieb:

    Der Compiler kann in eine struct Lücken einbauen, wenn er Lust hat, und die Größe eines Zeigers ist nicht einheitlich.

    Und deswegen auch nochmal von mir: IMMER mit sizeof arbeiten!


Anmelden zum Antworten