3 回答
TA贡献1877条经验 获得超1个赞
C标准不允许将函数指针转换为void*。您只能转换为其他函数指针类型。在C11标准6.3.2.3§8中:
指向一种类型的函数的指针可以转换为指向另一种类型的函数的指针,然后再次返回
重要的是,在使用指针调用该函数之前,必须先强制转换回原始类型(从技术上讲,是兼容类型。在6.2.7中定义为“ compatible” )。
请注意,由于使用的上下文不同,许多(但不是全部)C编译器也必须遵循POSIX标准,该标准要求可以将函数指针转换为void*反向。这对于某些系统功能(例如dlsym)是必需的。
TA贡献1811条经验 获得超4个赞
不幸的是,该标准不允许在数据指针和函数指针之间进行强制转换(因为在某些晦涩难懂的平台上可能没有意义),即使POSIX和其他平台也需要强制转换。一种解决方法不是强制转换指针,而是强制将指针强制转换为指针(编译器可以这样做,并且它将在所有普通平台上完成工作)。
typedef void (*FPtr)(void); // Hide the ugliness
FPtr f = someFunc; // Function pointer to convert
void* ptr = *(void**)(&f); // Data pointer
FPtr f2 = *(FPtr*)(&ptr); // Function pointer restored
TA贡献1820条经验 获得超2个赞
关于数据指针和代码指针,我有三个经验法则:
千万不能混用数据指针和代码指针
不要混用数据指针和代码指针
永远不要混合使用数据指针和代码指针!
在以下功能中:
void setCallback(const void *fnPointer)
{
gfnPtr = *((FN_GET_VAL*) (&fnPointer));
}
您有一个指向函数指针的数据指针。(更不用说您通过首先获取指针本身的地址,然后将其转换为指向指针的指针,然后再取消对其引用)来执行此操作。
尝试将其重写为:
void setCallback(FN_GET_VAL fnPointer)
{
gfnPtr = fnPointer;
}
另外,您可以(或应该)在设置指针时放弃演员表:
main()
{
setCallback(myfunc);
gfnPtr();
}
另外,您现在可以使用编译器执行的常规类型检查。
- 3 回答
- 0 关注
- 1009 浏览
添加回答
举报