是否可以在 c 中将结构指针转换为函数指针?

Is it possible to cast struct pointer to function pointer in c?

从这里:ISO C Void * and Function Pointers,我找到了将 (void*) 转换为函数指针的解决方法:

int
main(int argc, char *argv[])
{
    ...
    void (*funcp)(void);        /* Pointer to function with no arguments */
    ...
    *(void **) (&funcp) = dlsym(libHandle, argv[2]);
}

换句话说 - 取消引用双指针(另一个间接级别)。

现在仍然假设最终函数是 void(*)() 类型,但我想让其他函数“类型”可以使用转换,例如可以接受一些参数。

然后我找到了另一个解决方法,如何在结构 中包装函数指针:

typedef struct
{
   void (*ptr)(void);
} Func;

Func vf = { voidfunc };

所以我想合并这两个想法,并使通过结构将任意函数类型作为函数指针传递成为可能:

#include <stdio.h>

struct s{
    int a, b;
    void (*func)();
};

typedef struct{
    int (*add)(int,int);
} Func;

int add(int a, int b) { return a+b; }

int main(){
    Func f = {add};
    struct s foo = {.func=(void*)(&f)};
    printf("%i\n",f.add(1,2));
    printf("%i\n",foo.func(1,2));
}

不幸的是,它给出了错误:

invalid use of void expression

所以问题是,如何在 printf 语句中将类型 (void*) 转换回 (int*)(int,int)

即使您将函数更改为 return int (int (*func)();) 并且最终它会编译,您的代码也是错误的。

调用函数指针实际上是对该指针的解引用

当您将结构的地址分配给函数指针时,调用此函数实际上将执行结构内部的数据——而不是函数引用的结构成员。当然不会成功。

https://godbolt.org/z/GE464T

以下示例是一个 UB,但适用于 x86 和 arm 机器,仅用于说明目的..

struct s{
    int a, b;
    int (**func)();
};

typedef struct{
    int (*add)(int,int);
} Func;

int add(int a, int b) { return a+b; }

int main(){
    Func f = {add};
    struct s foo = {.func=(void*)(&f)};
    printf("%i\n",f.add(1,2));
    printf("%i\n",(*foo.func)(1,2));
}

https://godbolt.org/z/rKvGEG

或者如果你想在 struct

中使用 void (**)() 指针
typedef int func();

struct s{
    int a, b;
    void (**func)();
};

typedef struct{
    int (*add)(int,int);
} Func;

int add(int a, int b) { return a+b; }

int main(){
    Func f = {add};
    struct s foo = {.func=(void*)(&f)};
    printf("%i\n",f.add(1,2));
    printf("%i\n",((func *)(*foo.func))(1,2));
}

https://godbolt.org/z/M9qzdf

typedef int func();

struct s{
    int a, b;
    void (*func)();
};

typedef struct{
    int (*add)(int,int);
} Func;

int add(int a, int b) { return a+b; }

int main(){
    Func f = {add};
    struct s foo = {.func=(void*)(&f)};
    printf("%i\n",f.add(1,2));
    printf("%i\n",(*((func **)foo.func))(1,2));
}

或没有类型定义

struct s{
    int a, b;
    void (*func)();
};

typedef struct{
    int (*add)(int,int);
} Func;

int add(int a, int b) { return a+b; }

int main(){
    Func f = {add};
    struct s foo = {.func=(void*)(&f)};
    printf("%i\n",f.add(1,2));
    printf("%i\n",(*((int (**)())foo.func))(1,2));
}

https://godbolt.org/z/YG9xd7