1

我想问是否有可能使函数指针可以分配给我以后拥有的任何函数。

typedef struct 
{
    char *name ;
    void (*func0)(void) ;
}option;

int test(int i)
{
    return i;
}

如何转换选项参数或函数,以便稍后我可以调用选项参数并将其用作函数?
我试过:

op.func0= test ;
或:
(int)op.func0= test ;
失败。

4

3 回答 3

5

在 C 中,您可以将函数存储为

void * (*func)();

func = test;

但是当你调用它时,你必须将它转换为适当的类型

int ret = ((int (*)())func)(a);

这在任意目标架构上被认为是不安全的。在 x86 上它应该可以工作,但您应该避免在其他架构上使用这些技巧。

编辑:

如果您希望避免类型转换警告,请将分配设为

func = (void * (*)())test;

使用这种类型转换,它可以编译gcc -pedantic

于 2013-08-13T12:32:25.200 回答
1

可以将您的函数转换为不同的函数指针类型,您只需确保在使用它之前将其转换回来。这是一个例子:

#include <stdio.h>

typedef struct 
{
    char *name ;
    void (*func0)(void) ;
} option;

int test(int i)
{
    return i;
}

int main(int argc,char **argv)
{
    option a;
    int i;

    a.func0 = (void(*)(void))test;
    i = ((int(*)(int))a.func0)(5);
    printf("%d\n",i);
    return 0;
}

它输出5.

于 2013-08-13T12:45:30.423 回答
0

如果您对调用签名有一个有限的(即实际的)限制,您可能能够使用不同签名的指针的联合:

typedef union call_sigs_union
{
    无效 *void_void; // 纯空指针
    int (*int_sig_void)(void); // 返回不带参数的整数
    int (*int_sig_int)(int); // 返回带有单个 int arg 的整数
  . . .
} sigs_t;

这样做的好处是,如果你做错了什么,你可以从编译器中得到更好的警告,而不是强制转换所有内容。

警告:这在许多体系结构中都不能保证,因为理论上,不同的返回类型,也许还有签名,可以有不同的指针类型。虽然我已经阅读了一些系统,但这实际上发生在我没有听说过流行使用的主要参与者有这种行为。Intel X86、Itanimum、Sun SPARC 和 IBM RISC 是我使用过的一些性能良好的系统。注意到我已经阅读了 ARM 架构,这让我相信这些会很麻烦。

奇怪的行为通常仅限于专用处理器。任何人都可以在这会中断的系统上刷新我的记忆吗?

于 2013-08-13T12:54:23.210 回答