c++ - C++ 中的函数指针转换

标签 c++ casting function-pointers

我有一个 dlsym() 返回的 void 指针,我想调用 void 指针指向的函数。 所以我通过强制转换进行类型转换:

void *gptr = dlsym(some symbol..) ;
typedef void (*fptr)();
fptr my_fptr = static_cast<fptr>(gptr) ;

我也尝试过 reinterpret_cast 但没有运气,尽管 C cast 运算符似乎可以工作..

最佳答案

在 C++98/03 中不允许将 void* 直接 转换为函数指针(不应使用任何类型转换进行编译)。 C++0x 有条件地支持它(实现可以选择定义行为,如果确实定义了行为,那么它必须按照标准所说的去做。定义的 void*按照 C++98/03 标准,是指向对象而不是包含函数指针或成员指针。

知道您所做的工作在很大程度上依赖于实现,这里有一个选项应该在大多数平台上编译和工作(假设 32 位指针,对于 64 位使用 long long),即使它根据标准,显然是未定义的行为:

void *gptr = dlsym(some symbol..) ;
typedef void (*fptr)();
fptr my_fptr = reinterpret_cast<fptr>(reinterpret_cast<long>(gptr)) ;

这是另一个应该编译和工作的选项,但带有与上面相同的警告:

fptr my_ptr = 0;
reinterpret_cast<void*&>(my_ptr) = gptr; 

或者,在慢动作中......

// get the address which is an object pointer
void (**object_ptr)() = &my_ptr;  

// convert it to void** which is also an object pointer
void ** ppv = reinterpret_cast<void**>(object_ptr);

// assign the address in the memory cell named by 'gptr' 
// to the memory cell that is named by 'my_ptr' which is
// the same memory cell that is pointed to 
// by the memory cell that is named by 'ppv'
*ppv = gptr;  

它本质上利用了函数指针的地址是一个对象指针(void (**object_ptr)())这一事实——所以我们可以使用reinterpret_cast来将其转换为任何其他对象指针:例如 void**。然后我们可以沿着地址返回(通过取消引用 void**)到实际的函数指针,并将 gptr 的值存储在那里。

yuk - 绝不是定义明确的代码 - 但它应该可以满足您对大多数实现的期望。

关于c++ - C++ 中的函数指针转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1096341/

相关文章:

c++ - 如何在 X11 中创建没有框架的 GUI?

c++ - 使用 gcc 调试选项编译生产代码有什么副作用吗?

android - 你能把一个对象动态地转换成一个类吗?

c++ - 与模板类的链接错误

c++ - C++中不带virtual的多态实现多级继承

c++ - Visual C++ 和 C++ 有什么区别?

c++ - 如何递归删除Qt3DWindow根实体中的所有节点?

c# - 使用自定义类转换 IEnumerable<dynamic>

java - 在 Java 中转换引用变量

c - 对于 ANSI C 中的特殊应用,case 语句或函数指针数组是否更快?