2012-04-06 8 views
2

私の質問タイトルは私が何をしたいのかを完全には必ずしも明らかにしていませんが、私はCを使用しています、そしておそらく以下の擬似コードは、私がやろうとしているかを説明します:変数を使用して一般構造体メンバにアクセスする

typedef struct obj 
{ 
    char *str1; 
    char *str2; 
    char *str3; 
} object; 

/* global variable */ 
object *glob; 

void black_box_function(local, member) ???? 
{ 
    /* Do something with glob->member and local->member */ 
} 

void main() 
{ 
    object *ob1, *ob2; 

    /* Initialise glob, ob1 and ob2 somewhere */ 

    black_box_function(ob1, str1); 
    black_box_function(ob2, str3); 

} 

うまくいけば、あなたは私がやろうとしているかを見ることができます。私は特定のメンバーと何かをする "ブラックボックス"機能を持っており、どのメンバーが使用するかをブラックボックス機能に伝えることができる必要があります。

このコードのように、メンバーを関数に直接渡すだけで、残りのコードに簡単には収まらないためです。

black_box_function(ob1->member, glob->member) 
+1

なぜそれが収まらないのだろうか? – cnicutar

+0

あなたのメンバーが実際に 'str1'、' str2'などと呼ばれている場合(私はちょうどイラストレーションになるかもしれません)、なぜ配列を使用せず、関数にインデックスを渡すのですか? –

+0

はい、イラスト。実際には、他の人が書いたコードを使って、簡単に変更できないコードを使用しています。だから私は現在存在する構造体定義に固執する必要があります。 –

答えて

2

あなたは(GCCの拡張子を持つ)は、次の魔法を行うことができます:

#define black_box(local, member) black_box_function((local), __builtin_offsetof(object, member)) 

void black_box_function(object *local, int offset) 
{ 
    char *lmember = ((void *)local) + offset; 
    char *gmember = ((void *)global) + offset; 
    /* do stuff */ 
} 

ただし、事前にあなたのメンバーの種類を知っている必要があります。 Cは動的に型指定された言語ではないので、実行時イントロスペクションはまったくありません。 EDIT

あなたはこのように、GCCの拡張機能に頼ることなくoffsetof()機能を実装することができます

#define offsetof(type, field) ((int) (unsigned long) &((type *) 0)->field) 
+0

+1。 GCC拡張機能を使用していても、これはOPの要求に最も近いものです! –

+0

@PavanManjunath:ありがとう、 'offsetof'機能は、ポインタキャスティングマジックで、拡張子なしで実装できます。簡潔にするために組み込みのGCCバージョンを使用しました – C2H5OH

+0

なぜGCC拡張メソッドを削除しましたか?両方を保つ。方法1と方法2として名前を付けます。私の+1はあなたのGCC拡張メソッドのものでした:) –

2

おそらく、あなたは*あなたの構造体のアクセサ関数を作成し、すべてがcharであるため、代わりに直接

typedef struct 
{ 
    int a; 
    int b; 
} foo; 

typedef int* (*accessor)(foo*); 

int* get_a(foo* f) { return &f->a; } 
int* get_b(foo* f) { return &f->b; } 

void black_box_function(foo* object, accessor fn) 
{ 
    int* p = fn(object); 
} 

int main(void) 
{ 
    foo bar1; 
    foo bar2; 

    black_box_function(&bar1, get_a); 
    black_box_function(&bar2, get_b); 

    return 0; 
} 
+0

私はその提案が好きです - うまくいくと思います - ありがとう! –

1

をメンバーを渡すの関数ポインタの引数として、これらのアクセサを渡すことができ、あなたは次のように構造体を再定義することができます。

typedef struct obj 
{ 
    char **str; // Array of c 
} object; 

次に、あなたが作業対象となるメインからstrのインデックスを送信することができます

black_box_function(obj1, index) 

あなたはブラックボックスにobj1->str[i]のようにすることができます。

Btw、black-box_functionはコンパイルされません。

サイドノート:あなたのブラックボックス機能とコンパイル可能なコードに関するもう少し情報/コードは、あなたがやろうとしていることのより良いイメージを提供します。

+0

すべてが私の例ではchar *ですが、必ずしも実際のコードではありません。私は自分の質問の本質を何かに単純化することを試みた... 提案ありがとう... –

関連する問題