Declare a variable that is Defined in a struct

Consider the following struct defined in ModuleA:

typedef struct{
    int A;
    int B;
    int C[4];
}myStructType;

myStructType MyStruct;

If I wanted to use this struct from ModuleB, then I would declare the struct in the ModuleA header like this:

extern myStructType MyStruct;

So far, so good. Other modules can read and write MyStruct by including the Module A header file.

Now the question:

How can I declare only part of the struct in the Module A header file? For example, if I wanted ModuleB to be able to read and write MyStruct.C (or, to make things a bit easier, perhaps MyStruct.A or MyStruct.B), but not necessarily know that it's in a struct or know about elements A and B.

Edit: I should probably also specify that this will go in an embedded system which does basically all of its memory allocation at compile time, so we can be extremely confident at compile time that we know where MyStruct is located (and it's not going to move around).

Edit2: I'll also clarify that I'm not necessarily trying to prevent other modules from accessing parts of the struct, but rather, I'm attempting to allow other modules to access individual elements without having to do MyStruct.Whatever because other modules probably only care about a single element and not the whole structure.


You would have to encapsulate it, ie make a private variable such as:

static myStructType the_struct;

in some C file, and then provide an API to get access to the parts:

int * getC(void)
{
  return the_struct.C;
}

this would then let other C files get access to an integer array by calling

int *some_c = getC();
some_c[0] = 4711;

or whatever. It can be made "tighter" by being more explicit about the length of the returned array of course, I aimed for the minimal solution.


While in theory there might be some problems with the cleanliness of this solution (eg structure alignment), in practice it usually works if it compiles and if it doesn't compile, you can alter the structures to make it compile:

#include <stddef.h>

#define C_ASSERT(expr) extern char CAssertExtern[(expr)?1:-1]

// You keep this definition private to module A (e.g. in a .c file):
typedef struct
{
    int A;
    int B;
    int C[4];
} PrivateStruct;

// You expose this definition to all modules (in an .h file):
typedef struct
{
    char reserved[2*sizeof(int)];
    int C[4];
} PublicStruct;

// You put these in module A (in a .c file):
C_ASSERT(sizeof(PrivateStruct) == sizeof(PublicStruct));
C_ASSERT(offsetof(PrivateStruct,C) == offsetof(PublicStruct,C));

int main(void)
{
  return 0;
}

In the public .h file you can lie to the world about the global variable type:

extern PublicStruct MyStruct; // It's "PrivateStruct MyStruct;" in module A

If the two structure definitions go out of sync, you get a compile-time error (match, mismatch).

You will need to manually define the size of the reserved part of PublicStruct , perhaps by trial and error.

You get the idea.


To make the long story short — you can't. To make it a bit longer, you can't reliably do it.

链接地址: http://www.djcxy.com/p/73586.html

上一篇: 如何避免C中的未定义符号

下一篇: 声明一个在结构中定义的变量