Daten kapseln in C? Geht das?



  • Ist es möglich in C Daten und Funktionen auf die Daten in einem Modul (*.h und *.c File) zu kapseln?

    Konkret heißt das, ich will eine Datenstruktur definieren und Methoden um die Daten der Struktur zu modifizieren, will aber verhindern, dass ein anderes Modul direkt die Daten modifizieren kann. Geht das?

    Bsp.:
    logmsg.h

    #define LM_ERROR   1
    #define LM_WARNING 2
    #define LM_DEBUG   3
    
    struct Log {
      char * file;
      int loglevel;
    }
    char * lm_getLogfilename(void);
    int    lm_getLoglevel(void);
    void   lm_setLogfilename(char *n);
    void   lm_setLoglevel(int l);
    void   lm_init(char * name, int level);
    

    Um dann im Hauptprogramm, der Art:
    test_main.c

    #include "logmsg.h"
    Log * l;
    l = lm_init("test.log", LM_DEBUG);
    
    /* das soll einen Fehler ergeben, der Art, kein Zugriff auf ... */
    l->loglevel = LM_DEBUG;
    
    // ... weiter im Text
    


  • Du könntest im Header die Struktur nur deklarieren und in der Code-Datei definieren.



  • Ja, du kannst dafür sorgen, dass ein Typ zwar in jedem deiner Projekte bekannt ist, aber auf seine Elemente nur in dem einen Projekt zugegriffen werden kann.

    Das ist aber relativ umständlich und meiner Meinung nach nicht zu empfehlen. Unsere Software ist voll davon, und man verliert sehr schnell den roten Faden, da ein Typ eben nicht an jeder Stelle gleich interpretiert wird...

    myProject.h

    #ifndef MYPROJECT_H
    #define MYPROJECT_H
    
    typedef struct tag_MyProjectHandle {  //richtige Deklaration der Struktur
      int InternalID;     //irgendwelche Member
      HANDLE hFile;
      int Hostadapter;
      int Target;
      int Lun;
    } T_MyProjectHandle;
    
    #endif
    

    Shared.h

    #ifndef MYPROJECT_H
      typedef void *T_MyProjectHandle;  //Dummy-Deklaration
    #endif
    

    myProject.c

    #include "myProject.h"  //T_MyProjectHandle ist richtige Struktur
    #include "Shared.h"     //T_MyProjectHandle wird nicht neu definiert
    
    T_MyProjectHandle *handle;
    int iTemp=handle->Target;  //klappt
    

    myOtherProject.c

    #include "Shared.h"  //T_MyProjectHandle wird als void* definiert
    
    T_MyProjectHandle *handle;
    int iTemp=handle->Target;  //klappt nicht, da handle nur ein void Pointer ist
    


  • Eine Möglichkeit der Kapselung wäre, das du nur Nummern ( Handles )rausrückst und über diese Nummern deine Strukturen verwaltest.



  • rüdiger schrieb:

    Du könntest im Header die Struktur nur deklarieren und in der Code-Datei definieren.

    wie soll das gehen?



  • _matze schrieb:

    Ja, du kannst dafür sorgen, dass ein Typ zwar in jedem deiner Projekte bekannt ist, aber auf seine Elemente nur in dem einen Projekt zugegriffen werden kann.

    Das ist aber relativ umständlich und meiner Meinung nach nicht zu empfehlen. Unsere Software ist voll davon, und man verliert sehr schnell den roten Faden, da ein Typ eben nicht an jeder Stelle gleich interpretiert wird...

    myProject.h

    #ifndef MYPROJECT_H
    #define MYPROJECT_H
    
    typedef struct tag_MyProjectHandle {  //richtige Deklaration der Struktur
      int InternalID;     //irgendwelche Member
      HANDLE hFile;
      int Hostadapter;
      int Target;
      int Lun;
    } T_MyProjectHandle;
    
    #endif
    

    Shared.h

    #ifndef MYPROJECT_H
      typedef void *T_MyProjectHandle;  //Dummy-Deklaration
    #endif
    

    myProject.c

    #include "myProject.h"  //T_MyProjectHandle ist richtige Struktur
    #include "Shared.h"     //T_MyProjectHandle wird nicht neu definiert
    
    T_MyProjectHandle *handle;
    int iTemp=handle->Target;  //klappt
    

    myOtherProject.c

    #include "Shared.h"  //T_MyProjectHandle wird als void* definiert
    
    T_MyProjectHandle *handle;
    int iTemp=handle->Target;  //klappt nicht, da handle nur ein void Pointer ist
    

    Hi _matze,

    habe die Tags mal eingebaut, aber bei mir geht´s der Zugriff auf das Member-Element dummerweise so und so 😞

    Kannst du mal in den Code schauen, was ich da falsch mache?

    http://opensvn.csie.org/c_cpp_programming_sources/logmsg/



  • Tut mir leid, ich hatte ein paar Tage gar keine Zeit. Ich guck's mir aber morgen an und kann dir hoffentlich helfen...



  • Also ich habe gerade doch mal kurz 'reingeschaut. Ich habe das starke Gefühl, dass du dir meinen Post nicht richtig angesehen hast. Du hast ja lediglich die Definition des structs geändert (tag-Name). Zu einem solchen Konstrukt, wie ich es vorgeschlagen (?) habe, gehört wesentlich mehr. Der Knackpunkt ist ja gerade, dass es für deine Struktur zwei Definitionen in zwei verschiedenen Headern geben muss (eine Dummy-Definition). Je nach Verwendungszweck wird der entsprechende Header eingebunden. Damit man den Shared-Header (der ja von allen Moduln und Projekten eingebunden können werden sollte) auch nutzen kann, wenn man nicht die Dummy-, sondern die echte Definition benötigt, fragt man die include-guards ab (#ifndef).

    Wenn du noch daran Interesse hast, dann versuche nochmal, die ganze Sache halbwegs umzusetzen. Ich habe dich aber gewarnt, dass dein Code aufgebläht wird und ein wenig Übersicht flöten geht. Ob sich das wirklich lohnt ist die Frage, die du dir stellen musst...


Anmelden zum Antworten