我需要将函数引用存储为char *,稍后仅使用char *调用该函数。
我正在寻找类似的东西:
char* funcRef = (char*)myFunc;
//...
(void (*funcRef)())();
你是怎么做到的? (注意:我不是要求如何通过引用调用函数,只要它可以将对它的引用存储为char *然后将其转换回来)
答案 0 :(得分:5)
不允许进行此转换。允许的转换在 6.3转换,子小节 6.3.2.3指针一节中给出,其中段落(6)和(8)适用于函数指针。
- 任何指针类型都可以转换为整数类型。除了之前指定的,结果是实现定义的......
醇>
和
- 指向一种类型的函数的指针可以转换为指向另一种类型的函数的指针,然后再返回;结果应该等于原始指针。如果转换的指针用于调用类型与指向类型不兼容的函数,则行为未定义。
醇>
指向函数的指针和指向对象的指针之间的转换不在允许列表中;因此不允许。
有些系统指向函数的指针和指向对象的指针不可互换。最明显的情况是函数指针的大小与对象指针的大小不同,例如哈佛架构,或Compact或Medium模型中的8086。
答案 1 :(得分:1)
您的代码不起作用的原因是因为char*
指针不是函数指针。您不能将char*
称为函数。在将指针用作函数指针之前,需要将该指针强制转换回函数指针。
请注意:这是否完全可用于编译器和系统。
C标准中没有任何内容可以说明将指向函数的指针转换为指向对象的指针,反之亦然。这是未定义的行为。另一方面,POSIX标准要求兼容的实现必须能够将指向void的指针转换为指向函数的指针。 (注意:不需要反向功能。)
此问题也标记为C ++。在C ++ 11之前,将指向函数的指针转换为指向对象的指针(反之亦然)是非法的。编译器必须发出诊断消息。在符合POSIX的系统上,编译器将发出诊断信息,然后生成符合POSIXly的目标代码。在C ++ 11及更高版本中,有条件地支持将指向函数的指针转换为指向对象的指针,反之亦然。
有了这些警告,以下工作在我的POSIX兼容机器上,有多个编译器。是否适用于非POSIX投诉编译器的非POSIX兼容机器是任何人的猜测。
C ++版本:
#include <iostream>
int sqr (int k) { return k*k; }
int p42 (int k) { return k+42; }
void call_callback(void* vptr, int k)
{
using Fptr = int(*)(int);
Fptr fun = reinterpret_cast<Fptr>(vptr);
std::cout << fun(k) << '\n';
}
int main ()
{
call_callback(reinterpret_cast<void*>(sqr), 2);
call_callback(reinterpret_cast<void*>(p42), 2);
}
C版:
#include <stdio.h>
int sqr (int k) { return k*k; }
int p42 (int k) { return k+42; }
void call_callback(void* vptr, int k)
{
printf ("%d\n", ((int(*)(int))(vptr))(k));
}
int main ()
{
call_callback((void*)(sqr), 2);
call_callback((void*)(p42), 2);
}