简体   繁体   English

是否可以将结构指针转换为 c 中的 function 指针?

[英]Is it possible to cast struct pointer to function pointer in c?

From here: ISO C Void * and Function Pointers , I have found a workaround to cast (void*) to function pointer:从这里: ISO C Void * 和 Function 指针,我找到了将(void*)转换为 function 指针的解决方法:

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

In other words - to dereference double pointer (another level of indirection).换句话说 - 取消引用双指针(另一个间接级别)。

Now that still assumes, that the final function is of void(*)() type, but I would like to make cast available to other function "types" that can for example accepts some arguments.现在仍然假设,最终的 function 是void(*)()类型,但我想让转换可用于其他 function “类型”,例如可以接受一些 ZDBC11CAA5BDA29F77E8FB4EDDABD8。

Then I found another workaround how to wrap function pointer in struct Why can't I cast a function pointer to (void *)?然后我找到了另一种解决方法,如何在结构中包装 function 指针为什么我不能将 function 指针转换为(void *)? :

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

Func vf = { voidfunc };

So I would like to merge these 2 ideas and make possible to pass arbitrary function type as function pointer via struct:所以我想合并这两个想法,并可以通过结构将任意 function 类型作为 function 指针传递:

#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));
}

Unfortunately, it gives the error:不幸的是,它给出了错误:

invalid use of void expression

So the question is, how to cast back the type (void*) to (int*)(int,int) inside of the printf statement?所以问题是,如何在printf语句中将类型(void*)转换为(int*)(int,int)

even if you change the function to return int (int (*func)();) and eventually it will compile, your code is wrong.即使您将 function 更改为 return int (int (*func)();) 并最终编译,您的代码也是错误的。

Calling the function pointer is in the fact a dereferencing of this pointer.调用 function 指针实际上是对该指针的取消引用。

When you assign the function pointer with the address of the struct, calling this function will actually execute the data inside the struct - not the function referenced struct member.当您使用结构的地址分配 function 指针时,调用此 function 将实际执行结构内的数据 - 而不是 function 引用成员。 It of course will not be successful.当然不会成功。

https://godbolt.org/z/GE464T https://godbolt.org/z/GE464T

The following example is an UB but works on x86 & arm machines and it is only for the illustrational purposes..以下示例是 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 https://godbolt.org/z/rKvGEG

or if you want to use the void (**)() pointer in struct或者如果你想在 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 https://godbolt.org/z/M9qzdf

or或者

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));
}

or without typedefs或没有 typedef

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 https://godbolt.org/z/YG9xd7

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM