Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1952693
  • 博文数量: 261
  • 博客积分: 8073
  • 博客等级: 中将
  • 技术积分: 2363
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-10 15:23
文章分类

全部博文(261)

文章存档

2013年(1)

2012年(1)

2011年(50)

2010年(34)

2009年(4)

2008年(17)

2007年(55)

2006年(99)

分类:

2010-09-12 20:37:58

将一段程序移植到Solaris平台,编译过程时出现如下错误:

line 153 :error ISO C++ forbids casting between pointer-to-function and pointer-to-object

line 153 源代码:

m_decodeFunc = reinterpret_cast< DecodeFunc >( pHDLL->GetExportedFunc( TDSERVER_DECODERFUNC_NAME.c_str()) );

////////////////////////////////////////////////////////////////////////

Answer & Resolution :

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 d). 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(reinterpret_cast(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 ...  
void (*(*object_ptr))() = &my_ptr;  // get the address which is an object pointer 
 
// convert it to void** which is also an object pointer 
void ** ppv = reinterpret_cast<void**>(object_ptr);   
*ppv = gptr;  // 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' 

Since the above code is a little cryptic, the following explanation might help: 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.

阅读(865) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~