2012-10-08 57 views
2

考虑定义的变量下面的结构在ModuleA定义声明其在结构

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

myStructType MyStruct; 

如果我想用从ModuleB这个结构,那么我会声明在ModuleA的结构头像是这样的:

extern myStructType MyStruct; 

到目前为止,这么好。其他模块可以通过包含Module A头文件来读写MyStruct。

现在的问题是:

我怎样才能声明只能在模块头文件的结构的一部分?例如,如果我希望ModuleB能够读取和写入MyStruct.C(或者为了使事情变得更简单,可能是MyStruct.A或MyStruct.B),但不一定知道它在结构中或知道元素A和B.

编辑:我也许应该指定这将在嵌入式系统中执行,它基本上在编译时进行所有的内存分配,所以我们可以在编译时非常自信地知道MyStruct在哪里位于(并且它不会移动)。

EDIT2:我还要澄清一点,我并不想防止其他模块访问该结构的部分,而是,我试图允许其他模块访问单个元素,而无需去做MyStruct.Whatever,因为其他模块可能只关心单个元素而不关注整个结构。

回答

3

你将不得不将其封装,即做一个私有变量如:

static myStructType the_struct; 
在一些C文件

,然后提供一个API来获取访问部分:

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

这会让其他C文件通过调用

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

或其他任何东西来获得访问整数数组的权限。它可以通过更清楚地了解返回数组的长度而变得更“紧密”,我的目标是达到最小的解决方案。

1

为了使长话短 - 你不能。为了使它更长一点,你不能可靠地做到这一点。

+1

肯定有办法做到这一点,如果我们包括丑陋的黑客是可能的答案。例如:#define StructElementA((&MyStruct.A)*)no? –

+0

是的,为了让故事更长,例如,可以用填充符而不是“不可访问”元素声明结构。但是这不会是可靠的。不过,不知道你的'#define'如何解决这个问题。 –

1

你可以尝试用一种吸气剂:

在ModuleA

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

myStructType MyStruct; 

int getA() 
{ 
    return MyStruct.A; 
} 

等。

而是切换到C++

0

你不能做的正是你所描述什么,但它是常见的有作为标题,这是连续与它有它的内部只知道一个缓冲区一个struct特定模块。

这是相当清楚该结构是头,但它仍然可以作为一个例子:

typedef struct _FILE_NOTIFY_INFORMATION { 
    ULONG NextEntryOffset; 
    ULONG Action; 
    ULONG NameLength; 
    ULONG Name[1]; 
} FILE_NOTIFY_INFORMATION, *PFILE_NOTIFY_INFORMATION; 

这个结构(从微软NativeSDK)被设计为一个可变长度的缓冲器的头部。所有模块都可以通过查看NameLength来计算缓冲区的时间长度,但您可以使用此方法将任何内容存储在缓冲区中。这可能只被一个特定的模块知道,其他人只是使用长度来复制它等。

2

尽管理论上可能存在一些与此解决方案(例如结构对齐)的清洁有关的问题,但实际上它通常工作,如果它编译,如果它不编译,你可以改变结构,使其编译:

#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; 
} 

在公共.h文件中,你可以骗全世界大约全局变量类型:

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

如果两个结构定义超出s ync,你会得到一个编译时错误(match,mismatch)。

您需要手动定义PublicStruct的保留部分的大小,也许需要反复试验。

你明白了。

0

如果不是用于隐藏,而是用于结构化,那就去构造它。例如,像这样:

moduleA.h:

typedef struct{ 
    int A; 
}myStructModuleAType; 

extern myStructModuleAType myStructModuleA; 

moduleA.c:

myStructModuleAType myStructModuleA; 

moduleB.h:

typedef struct{ 
    int B; 
}myStructModuleBType; 

extern myStructModuleBType myStructModuleB; 

moduleB.c:

myStructModuleBType myStructModuleB; 

main.h:

#include "moduleA.h" 
#include "moduleB.h" 

typedef struct{ 
    myStructModuleAType * pmyStructModuleA; 
    myStructModuleBType * pmyStructModuleB; 
    int C[4]; 
}myStructType; 

extern myStructType myStruct; 

的main.c:

#include "main.h" 

myStructType myStruct; 

myStructType myStruct = { 
    .pmyStructModuleA = &myStructModuleA 
    .pmyStructModuleB = &myStructModuleB 
};