是否可以在 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)();) 并且最终它会编译,您的代码也是错误的。
调用函数指针实际上是对该指针的解引用
当您将结构的地址分配给函数指针时,调用此函数实际上将执行结构内部的数据——而不是函数引用的结构成员。当然不会成功。
以下示例是一个 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));
}
或者如果你想在 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));
}
或
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));
}
从这里: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)();) 并且最终它会编译,您的代码也是错误的。
调用函数指针实际上是对该指针的解引用
当您将结构的地址分配给函数指针时,调用此函数实际上将执行结构内部的数据——而不是函数引用的结构成员。当然不会成功。
以下示例是一个 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));
}
或者如果你想在 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));
}
或
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));
}