我有一个 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/