函数原型与void *参数

时间:2013-12-11 18:17:22

标签: c void-pointers function-prototypes

我有两个函数,每个函数都有一个指向不同类型的指针:

void processA(A *);
void processB(B *);

是否有一个函数指针类型能够在没有强制转换的情况下保存指向任一函数的指针? 我试着用

typedef void(*processor_t)(void*);
processor_t Ps[] = {processA, processB};

但它不起作用(编译器抱怨指针初始化不兼容)。

编辑:代码的另一部分将遍历Ps的条目,而不知道类型。此代码将传递char *作为参数。像这样:

Ps[i](data_pointers[j]);

编辑:谢谢大家。最后,我可能会使用这样的东西:

void processA(void*);
void processB(void*);

typedef void(*processor_t)(void*);
processor_t Ps[] = {processA, processB};

...

void processA(void *arg)
{
  A *data = arg;
  ...
}

3 个答案:

答案 0 :(得分:4)

如果你typedef void (*processor_t)();那么这将在C中编译。这是因为一个空的参数列表将函数的参数的数量和类型保留为未指定的,所以这个typedef只定义一个类型,它是“函数返回的指针void,取未指定数量的未指定类型的参数。“

编辑:顺便说一句,您不需要初始化列表中函数名称前面的&符号。在C中,该上下文中的函数名称衰减为指向函数的指针。

答案 1 :(得分:1)

如果你施放它们就可以了

processor_t Ps[] = {(processor_t)processA, (processor_t)processB};

顺便说一句,如果你的代码被这种类型的东西所驱使,switch遍布整个地方以确定你需要调用哪个函数,你可能想看看面向对象的编程。我个人不喜欢它(特别是C ++ ...),但它确实很好地删除了这种带有虚拟继承的代码。

答案 2 :(得分:1)

使用union可以在没有强制转换的情况下完成:

typedef struct A A;
typedef struct B B;

void processA(A *);
void processB(B *);

typedef union { void (*A)(A *); void (*B)(B *); } U;

U Ps[] = { {.A = processA}, {.B = processB} };

int main(void)
{
    Ps[0].A(0); // 0 used for example; normally you would supply a pointer to an A.
    Ps[1].B(0); // 0 used for example; normally you would supply a pointer to a B.
    return 0;
}

必须使用正确的成员名称调用该函数;此方法只允许您在每个数组元素中存储一个指针或另一个指针,而不是执行奇怪的函数别名。


另一个替代方法是使用具有所需类型的代理函数,该函数在使用指向char的指针调用并且使用其正确类型调用实际函数时具有所需类型:

typedef struct A A;
typedef struct B B;

void processA(A *);
void processB(B *);

typedef void (*processor_t)();

void processAproxy(char *A) { processA(A); }
void processBproxy(char *B) { processB(B); }

processor_t Ps[] = { processAproxy, processBproxy };

int main(void)
{
    char *a = (char *) address of some A object;
    char *b = (char *) address of some B object;
    Ps[0](a);
    Ps[1](b);
    return 0;
}

我上面使用了char *,因为您声明使用了它,但我通常更喜欢void *