[英]Declare a variable that is Defined in a struct
考慮以下在ModuleA中定義的結構:
typedef struct{
int A;
int B;
int C[4];
}myStructType;
myStructType MyStruct;
如果我想從ModuleB使用此結構,則可以在ModuleA標頭中聲明該結構,如下所示:
extern myStructType MyStruct;
到現在為止還挺好。 其他模塊可以通過包含模塊A頭文件來讀取和寫入MyStruct。
現在的問題是:
如何在Module A頭文件中僅聲明結構的一部分? 例如,如果我希望ModuleB能夠讀取和寫入MyStruct.C(或使事情變得容易一些,也許是MyStruct.A或MyStruct.B),但不一定知道它在結構中或對元素的了解A和B。
編輯:我可能還應該指定它將在嵌入式系統中運行,該系統在編譯時基本上會完成其所有內存分配,因此我們在編譯時可以非常有把握,因為我們知道MyStruct的位置(並且它不會移動)周圍)。
Edit2:我還要澄清一下,我並不一定要阻止其他模塊訪問該結構的某些部分,而是試圖允許其他模塊訪問各個元素而不必執行MyStruct。可能只關心單個元素,而不關心整個結構。
您必須封裝它,即創建一個私有變量,例如:
static myStructType the_struct;
在某些C文件中,然后提供API來訪問部件:
int * getC(void)
{
return the_struct.C;
}
然后,這將允許其他C文件通過調用以下內容訪問整數數組
int *some_c = getC();
some_c[0] = 4711;
管他呢。 通過更明確地說明返回數組的長度,可以使它“更緊密”,我的目標是最小的解決方案。
從理論上講,此解決方案的整潔度可能存在一些問題(例如,結構對齊),但實際上,如果可以編譯,如果不編譯,它通常可以工作,您可以更改結構以使其編譯:
#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
如果兩個結構定義不同步,則會出現編譯時錯誤( match , mismatch )。
您可能需要通過反復試驗來手動定義PublicStruct
保留部分的大小。
你明白了。
長話短說-您不能。 要使其更長一點,您將無法可靠地做到這一點。
您可以嘗試使用一種吸氣劑:
在ModuleA中:
typedef struct{
int A;
int B;
int C[4];
}myStructType;
myStructType MyStruct;
int getA()
{
return MyStruct.A;
}
等等。
而是切換到C ++
您無法完全按照自己的描述進行操作,但是將結構用作標頭是很常見的,它與緩沖區相鄰,而緩沖區的內部結構只有特定模塊才知道。
顯然,此結構的頭是什么,但仍可以作為示例:
typedef struct _FILE_NOTIFY_INFORMATION {
ULONG NextEntryOffset;
ULONG Action;
ULONG NameLength;
ULONG Name[1];
} FILE_NOTIFY_INFORMATION, *PFILE_NOTIFY_INFORMATION;
這個結構(來自Microsoft的NativeSDK)設計為可變長度緩沖區的標頭。 所有模塊都可以通過查看NameLength來確定緩沖區的長度,但是您可以使用此方法將任何內容存儲在緩沖區中。 只有特定的模塊才知道這一點,而其他模塊只是使用長度來復制它,等等。
如果不是為了隱藏而是為了結構化,則進行結構化。 例如:
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
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.