3

我遇到了 C 中的设计问题。

假设我有相当多的函数,具有不同的参数计数。

问题:

int print_one(int x)
{
    printf("one: %d\n", x);
    return 1;
}

int print_three(int x, int y, int z)
{
    printf("three: %d-%d-%d\n", x, y, z);
    return 3;
}

现在,我想将一些属性连接到结构中的这些函数,这样我就可以在不知道确切函数的情况下操作它们,包括它们的参数计数(我什至可以调用结构接口)

我像这样尝试过,(我认为这是非常错误的):

typedef int (*pfunc)(int c, ...);

typedef struct _stroffunc
{
    pfunc myfunction;
    int flags;
    int some_thing_count;
    int arguments[10];
    int argumentcount;
} stroffunc;

int main()
{
    stroffunc firststruct;

    firststruct.pfunc = (pfunc) print_two;
    firststruct.something_count = 101;
    arguments[0] = 102;
    argumentcount = 1;
    flag &= SOME_SEXY_FLAG;

    // now I can call it, in a pretty ugly way ... however I want (with patially random results ofc)
    firststruct.pfunc(firststruct.arguments[0]);
    firststruct.pfunc(firststruct.arguments[0], 124, 11);
    firststruct.pfunc(1, firststruct.arguments[0], 124, 1, 1);
}

我发现这个解决方案非常难看,我认为(希望)有一个更好的解决方案来调用 & 和设置函数指针。

我只是希望,我足够清楚......注意:我没有编译这段代码,但我编译并运行了一个非常相似的代码,所以这些概念是有效的。注意:需要纯 C

4

3 回答 3

1

通过可变参数函数指针调用非可变参数函数会导致未定义的行为。首先,回想一下可变参数函数的参数经过默认参数提升chars 转换为ints 等),这将完全搞砸。

目前尚不清楚您打算如何或为什么要动态调用具有不同数量参数的函数。但一种解决方案可能是使用联合:

typedef struct {
    int num_args;
    union {
        void (*f1)(int);
        void (*f2)(int, int);
        void (*f3)(int, int, int);
    } func;
} magic;


...

magic m;
...
switch (m.num_args) {
case 1: m.func.f1(arg1); break;
case 2: m.func.f2(arg1, arg2); break;
case 3: m.func.f3(arg1, arg2, arg3); break;
default: assert(0);
}

第二种解决方案是将所有函数重写为可变参数。

于 2012-04-16T20:32:59.103 回答
0

这是我知识的边缘,但我相信由于 ABI 中的不兼容性,您还需要使函数成为可变参数。

见:维基百科的例子

于 2012-04-16T19:50:47.647 回答
0

也许你可以添加一个库,它有一些函数来处理结构,比如“伪”类,

int initFunc(int (*pfunc)(int c,...));

该函数会将指针保存到结构中,就像 POO 中的上下文一样,在结构中,您将像使用所有函数的“映射”一样使用它,您将使用 id 调用每个函数。

它返回一个id,你把它保存在一个数组中,然后另一个函数说

int call(int id,int p1,...);

你说函数id和参数的地方,确定你现在必须哪个函数是每个id

于 2012-04-16T19:56:58.617 回答