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)
4

3 回答 3

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;
}
于 2012-04-06T11:15:42.720 回答
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)
于 2012-04-06T11:22:51.487 回答
1

由于都是 char*,因此您可以重新定义结构,如:

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

然后,您可以发送str要使用的 from main 的索引:

black_box_function(obj1, index)

所以你可以像obj1->str[i]在你的黑匣子里一样。

顺便说一句,black-box_function不会编译。

附带说明:关于您的黑盒功能和可编译代码的更多信息/代码可以更好地了解您正在尝试做什么。

于 2012-04-06T11:19:04.500 回答