在C ++中的函数指针 [英] Function pointers casting in C++

查看:133
本文介绍了在C ++中的函数指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



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

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

我也尝试过reinterpret_cast但没有运气,虽然C类型转换器似乎工作。 p>

转换 void *

解决方案

在C ++ 98/03中不允许直接使用到函数指针 (不应使用任何转换)。它在C ++ 0x中有条件地支持(一个实现可以选择定义行为,如果它定义它,那么它必须做标准说的应该做的事)。 void * ,由C ++ 98/03标准定义,意在指向对象,不包含函数指针或成员指针。



知道你是什么正在做的是严重依赖于实现,这里是一个选项,应该编译和工作(假设32位指针,使用long long为64位)在大多数平台,即使它是明显未定义的行为根据标准:

  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;

或者,在慢动作...

  //获取一个对象指针的地址
void(*(* object_ptr))()=& my_ptr;

//将其转换为void **也是一个对象指针
void ** ppv = reinterpret_cast< void **>(object_ptr);

//将以'gptr'
//命名的存储单元中的地址分配给由'my_ptr'命名的存储单元,它是
//相同的存储器由ppv命名的存储单元指向
//的单元
* ppv = gptr;

它本质上利用了函数指针的地址是一个对象指针 [void(*(* object_ptr))()] - 因此我们可以使用 reinterpret_cast 将其转换为任何其他对象指针: void ** 。然后我们可以通过返回地址(通过取消引用void **)到实际的函数指针,并存储gptr的值。



yuk - 定义的代码 - 但它应该做你期望它在大多数实现上做。



I have a void pointer returned by dlsym(), I want to call the function pointed by the void pointer. So I do a type conversion by casting:

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

I hav also tried reinterpret_cast but no luck, although the C cast operator seems to work..

Thanx,

解决方案

Converting a void* to a function pointer directly is not allowed (should not compile using any of the casts) in C++98/03. It is conditionally supported in C++0x (an implementation may choose to define the behavior and if it does define it then it must do what the standard says it should do. A void*, as defined by the C++98/03 standard, was meant to point to objects and not to contain function pointers or member pointers.

Knowing that what you are doing is heavily implementation dependent, here is one option that should compile and work (assuming 32 bit pointers, use long long for 64 bit) on most platforms, even though it is clearly undefined behavior according to the standard:

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

And here is another option that should compile and work, but carries the same caveats with it as the above:

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

Or, in Slow motion...

// 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;  

It essentially exploits the fact that the address of the function pointer is an object pointer [void (*(*object_ptr))()] - so we can use reinterpret_cast to convert it to any other object pointer: such as void**. We can then follow the address back (by dereferencing the void**) to the actual function pointer and store the value of the gptr there.

yuk - by no means well-defined code - but it should do what you expect it to do on most implementations.

这篇关于在C ++中的函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆