This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Access Struct variable from

Hello,

My project contains several files:

main.c
routines.c
config.h
etc.

In the main.c I make a structure like:

xdata struct StructUserRec{
		BYTE	XPIDNr[9];
		char	UserName[15];
		BYTE	ContrHour;
		BYTE	ContrMin;
		BYTE	WorkedHour;
		BYTE	WorkedMin;
		};

xdata struct StructUserRec UserRec[10];

In Config.H is the declaration:
extern struct StructUserRec UserRec[10];

How can I access this structure from Routines.C? I know how to do this with other variables. But it doesn't work.

My compiler gives an error like:
ROUTINES.C(75): error C230: 'StructUserRec': unknown struct/union/enum tag

How can you make structures accessible from different .C files?

Thanks in advance,

M. Joosse

Parents Reply Children
  • Another thought on this issue:

    If one of the structure members is a variable of which the type is an enum, then the enum also has to be put in the header file.

    Example:

    structdef( NvmItem )
    {
    #ifdef TESTING_MODULE_NVM
        Nat16   address;
    #else
        Nat8    address;
    #endif
        NvmType type;
        Nat8    length;
    };
    
    I had this declaration in a c-file and had to move it to the h-file before compilation could take place. That was the first step...

    structdef is #define'd as follows in the corresponding h-file:
    #define structdef( type )  extern struct _##type
    

    But... And here comes the second step I had to take...
    NvmType is an enum that was declared in the c-file (just before the structure):
    typedef enum
    {
        NvmBool = 0u
    ,   NvmByte
    ,   NvmInt
    ,   NvmBlock
    } NvmType;
    
    If I wanted to have a successful compilation, I had to put the enum in the header file too!

    Is this such a nice approach?

    -- Geert

  • But what about data hiding?

    Nothing particular about it --- hiding implementation details from users was never a prominent design aspect of C, and IMHO it shouldn't be. Let me put it like this, if your project is complex enough that the benefits of data hiding might become important, then C on the 51 almost certainly isn't the right platform anyway.

    That said, you can hide a large part of the details even in C, if you really think you have to, by means of a pointer to a struct type, whithout giving the definition of that struct.

  • That said, you can hide a large part of the details even in C, if you really think you have to, by means of a pointer to a struct type, whithout giving the definition of that struct.

    Just to learn: can you show me how to do this in my specific situation, given the examples above?

  • "If I wanted to have a successful compilation, I had to put the enum in the header file too"

    Well, of course you do!

    If you use any non-standard types, then you are obviously going to have to include the type definition with anything that relies upon that type!

    Why is this a problem to you?

    How else could it work?

  • "But what about data hiding?. Putting the definition into the header file uncovers the real implementation..."

    No, it doesn't.

    IF you've put something in a header file, then you're not hiding it, are you?
    You put stuff into a header file because you want to share it - not hide it!

    If you're going to share something, you obviously need to share both its name and its type - otherwise the "sharees" won't know what to do with it, will they?!

  • You can cast pointers to struct types among each other, as long as one struct type is just an extended version of the other. So you can have a "dummy struct type" exported by the header, with all the private data removed from view by a pointer cast:

    lib.h:

    struct dummy {
       int magic_cookie;
    };


    lib.c:

    struct real {
       int magic_cookie;
       /* private data: */
       double whatever;
       char lotofstuff[512];
       /* ... */
    };

    The exported interface would use pointers to struct dummy, which are cast into pointers to struct real by the implementation (in lib.c) whenever the private members are needed:

    foo_func(struct dummy *this) {
      struct real *real_this = (struct real *) this;
    
      real_this->whatever = 5.25;
    }
    

    The magic cookie provides a bit of protection against the potential evil of any explicit pointer cast.

  • "Why is this a problem to you?"
    Not anymore, Andy. I was confused at first since I had to move the struct into the header file.
    And of course, if a var is used in that struct that has a type defined in an enum, then that enum must be made public too!
    Otherwise, like you said, it can never work.

    -- Geert

  • "as long as one struct type is just an extended version of the other"

    Nice trick, never though about this one!

    Thanks Hans!

    -- Geert