2

ModuleAで定義されている次の構造体について考えてみます。

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

myStructType MyStruct;

ModuleBからこの構造体を使用したい場合は、次のようにModuleAヘッダーで構造体を宣言します。

extern myStructType MyStruct;

ここまでは順調ですね。他のモジュールは、モジュールAヘッダーファイルをインクルードすることにより、MyStructの読み取りと書き込みを行うことができます。

今の質問:

モジュールAヘッダーファイルで構造体の一部のみを宣言するにはどうすればよいですか?たとえば、ModuleBがMyStruct.Cを読み書きできるようにしたい(または、少し簡単にするために、おそらくMyStruct.AまたはMyStruct.B)が、構造体にあることや要素について知っているとは限らない場合AとB。

編集:これは、コンパイル時に基本的にすべてのメモリ割り当てを行う組み込みシステムで行われることも指定する必要があります。これにより、コンパイル時にMyStructがどこにあるかを非常に確信できます(移動しません)。その周り)。

Edit2:他のモジュールが構造体の一部にアクセスするのを必ずしも阻止しようとしているのではなく、他のモジュールがMyStructを実行せずに個々の要素にアクセスできるようにしようとしていることも明確にします。おそらく、構造全体ではなく、単一の要素のみを気にします。

4

6 に答える 6

3

それをカプセル化する必要があります。つまり、次のようなプライベート変数を作成します。

static myStructType the_struct;

いくつかのCファイルで、パーツにアクセスするためのAPIを提供します。

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

これにより、他のCファイルが呼び出して整数配列にアクセスできるようになります。

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

または何でも。もちろん、返される配列の長さをより明確にすることで、「よりタイト」にすることができます。私は最小限の解決策を目指しました。

于 2012-10-08T14:32:18.547 に答える
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;
}

public .hファイルでは、グローバル変数タイプについて世界に嘘をつくことができます。

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

2つの構造体定義が同期しなくなると、コンパイル時エラーが発生します(一致不一致)。

PublicStructおそらく試行錯誤によって、の予約部分のサイズを手動で定義する必要があります。

あなたはその考えを理解します。

于 2012-10-08T14:53:38.080 に答える
1

長い話を短くするために—あなたはできません。少し長くするために、確実に行うことはできません。

于 2012-10-08T14:23:43.383 に答える
1

あなたは一種のゲッターを使おうとすることができます:

ModuleAの場合:

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

myStructType MyStruct;

int getA()
{
    return MyStruct.A;
}

等々。

代わりにC++に切り替えてください

于 2012-10-08T14:32:19.920 に答える
0

説明したことを正確に行うことはできませんが、構造体をヘッダーとして使用するのが一般的です。これは、特定のモジュールにのみ知られている内部を持つバッファーと隣接しています。

この構造体がヘッダーの目的であることはかなり明白ですが、それでも例として機能します。

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

この構造体(Microsofts NativeSDKから)は、可変長バッファーのヘッダーになるように設計されています。すべてのモジュールは、NameLengthを調べることでバッファーの長さを計算できますが、このメソッドを使用して、それに付随するバッファーに何かを格納できます。これは、特定のモジュールだけが知っている可能性があり、他のモジュールは長さを使用してコピーするだけです。

于 2012-10-08T14:38:50.543 に答える
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
};
于 2012-10-08T15:32:28.807 に答える