2012-04-06 27 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 2012-04-06 11:08:14

+0

如果你的成员真的被称为'str1','str2'等(我赞赏可能只是作为例证),那么为什么不使用数组,并将索引传递给函数呢? – 2012-04-06 11:18:26

+0

是的,例证。其实,我正在使用别人写的代码,我不能轻易改变。所以我需要坚持现有的结构定义。 – 2012-04-06 11:56:25

回答

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不是一种动态类型语言,因此您根本没有运行时反思。

编辑:您可以实现offsetof()功能,而无需诉诸GCC的扩展,这样的:

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

+1。即使你使用GCC扩展,这也是最接近OP的请求! – 2012-04-06 11:32:23

+0

@PavanManjunath:谢谢,'offsetof'功能可以通过指针投射魔法实现,不需要扩展。为简洁起见,我使用了内置的GCC版本 – C2H5OH 2012-04-06 11:34:02

+0

为什么要删除GCC扩展方法?保持他们两个。将它们命名为方法1和方法2。我的+1是为你的GCC扩展方法:) – 2012-04-06 11:42:33

2

也许你能为你的结构创建存取功能,并通过这些访问器函数指针参数,而不是成员直接传递

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

我喜欢这个建议 - 认为它会很好地工作 - 谢谢! – 2012-04-06 11:58:12

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 *,但不一定在我的真实代码中。我试图提炼出我的问题的本质到一些简单的... 感谢您的建议,虽然... – 2012-04-06 11:47:36