【问题标题】:How can I cast a void function pointer in C?如何在 C 中强制转换 void 函数指针?
【发布时间】:2011-07-29 12:35:58
【问题描述】:

考虑:

#include <stdio.h>

int f() {
  return 20;
}

int main() {
    void (*blah)() = f;

    printf("%d\n",*((int *)blah())());  // Error is here! I need help!
    return 0;
}

我想将 'blah' 转换回 (int *) 以便我可以将其用作函数以在 printf 语句中返回 20,但它似乎不起作用。我该如何解决?

【问题讨论】:

  • 您使用与函数签名不匹配的函数指针是否有原因?
  • 真是个黑客。没有原型的函数,然后将返回 void 的函数指针重新解释为返回 int 的函数指针。我认为没有任何借口可以做这样的事情。
  • 是的,我可以让'blah'指向我想要的任何东西,从而节省变量:)
  • @Jens:其实有一个很好的借口;对于函数指针类型,这是实现 void * 等效项的唯一方法。可能会使用另一个变量来保存确定所指向函数的实际类型的信息,以便正确调用它。
  • 或者,如果 void (*)() 函数指针只是您传递给 API 的“上下文”的一部分,该 API 会被传递回回调函数,那么您可能静态地知道要转换到的类型调用它。

标签: c function pointers casting void


【解决方案1】:

这可能会解决它:

printf("%d\n", ((int (*)())blah)() ); 

【讨论】:

  • 除了编译器(这里 gcc 给出警告:initialization from incompatible pointer type 解决方案有效。
【解决方案2】:

您的代码似乎正在调用blah 指向的函数,然后尝试将其void 返回值强制转换为int *,这当然做不到。

您需要在调用函数之前转换函数指针。在单独的语句中执行此操作可能更清楚,但您可以按照您的要求在 printf 调用中执行此操作:

printf("%d\n", ((int (*)())blah)() );

【讨论】:

    【解决方案3】:

    与其初始化一个 void 指针并稍后重铸,不如立即将其初始化为一个 int 指针(因为您已经知道它是一个 int 函数):

    int (*blah)() = &f; // I believe the ampersand is optional here
    

    要在您的代码中使用它,您只需像这样调用它:

    printf("%d\n", (*blah)());
    

    【讨论】:

    • 你为什么不想这样?
    • @crashmstr 我的猜测是涉及到一个外部 API,他没有能力更改签名。
    • 如果“f”是一个外部API函数,那么它要么返回int,要么不返回。此外,从这个例子来看,似乎也没有理由使用函数指针。所以“有效但不是我想要的”仍然有点模糊。
    • @crash,我确信这个例子只是一个通用存根,但即使 OP 想要一个 void 函数指针稍后重铸为适当的类型,代码也必须知道提前知道该函数是什么类型,无论如何都会被硬编码。
    【解决方案4】:

    typedefint 版本:

    typedef int (*foo)();
    
    void (*blah)() = f;
    foo qqq = (foo)(f);
    
    printf("%d\n", qqq());
    

    【讨论】:

      猜你喜欢
      • 2018-03-05
      • 1970-01-01
      • 2016-08-29
      • 2011-07-31
      • 2012-11-21
      • 1970-01-01
      • 2011-02-15
      • 2012-01-10
      • 1970-01-01
      相关资源
      最近更新 更多