Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在c中是否可以将结构指针强制转换为函数指针?_C_Pointers_Casting_Function Pointers_Void Pointers - Fatal编程技术网

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

在c中是否可以将结构指针强制转换为函数指针?,c,pointers,casting,function-pointers,void-pointers,C,Pointers,Casting,Function Pointers,Void Pointers,从这里:,我找到了一个将(void*)转换为函数指针的解决方法: int main(int argc, char *argv[]) { ... void (*funcp)(void); /* Pointer to function with no arguments */ ... *(void **) (&funcp) = dlsym(libHandle, argv[2]); } 换句话说-取消对双指针的引用(另一个间接级别) 现在仍然假设

从这里:,我找到了一个将
(void*)
转换为函数指针的解决方法:

int
main(int argc, char *argv[])
{
    ...
    void (*funcp)(void);        /* Pointer to function with no arguments */
    ...
    *(void **) (&funcp) = dlsym(libHandle, argv[2]);
}
换句话说-取消对双指针的引用(另一个间接级别)

现在仍然假设,最后一个函数是
void(*)(
type),但是我想让cast对其他函数“type”可用,例如可以接受一些参数

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

因此,我希望合并这两种想法,并通过struct将任意函数类型作为函数指针传递:

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

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

即使将函数更改为返回
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));
}

或者如果要在结构中使用
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

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

即使您将指针更改为compile.Re“我找到了一个可转换的解决方法”:也许您的意思是您找到了一个可转换的解决方法。强制转换是执行转换的运算符,您不需要解决方法将
void*
强制转换为函数指针,因为您只需编写强制转换:
void(*funcp)(void)=(void(*)(void))dlsym(libHandle,argv[2])。这不是C标准所定义的,但它是允许的。如果您在支持
dlsym
的环境中工作,该环境记录为返回
void*
即代码或数据的地址,则该环境必须支持将
void*
转换为函数指针。它隐式地是与该环境一起使用的编译器的一部分(尽管这应该在文档中明确说明;保持隐式是低于标准的工程)。此外,如果C实现确实支持将
void*
转换为函数指针,它将通过一个简单的强制转换来实现。不太可能任何实现都不支持这一点,而是通过像您正在做的那样重新解释指针的位来支持它。这就增加了表示和别名的其他问题。您可以将
dlsym
的返回值强制转换为指向函数类型的适当指针。我不明白您试图对结构做什么,但它看起来像一个.re“问题是,如何将printf语句中的类型
(void*)
转换为
(int*)(int,int)
?:不要这样做。没有理由这样做。要打印任何指针,请使用
%p
,而不是
%i
,并将其转换为
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));
}