簡體   English   中英

聲明在結構中定義的變量

[英]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

如果兩個結構定義不同步,則會出現編譯時錯誤( matchmismatch )。

您可能需要通過反復試驗來手動定義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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM