2009年11月11日 星期三

Casting function pointers from void * in C++

在拿 DLL 裡的 symbol 時,它會回傳一個 void *,你必須要自己轉型成對應的 function pointer。不過問題是 C++98/03 都把 void * 視為指向某個物件的指標,而不會是一個 function pointer,所以使用 C++ style 轉型會失敗;既然標準沒有定義,就代表這種行為基本上是依賴實作的,為此我們需要一些怪怪的 reinterpret_cast
作法一,先轉成指標長度的整數,再轉成函式指標。
void * gptr = dlsym( ... );
typedef void ( * fptr )();
fptr my_fptr = reinterpret_cast< fptr >( reinterpret_cast< intptr_t >( gptr ) );
intptr_t 是 C99/C++0x 的新型別,一定是一個指標的大小,如果沒有辦法的話,也可以用 long 代替,大部分的平台上 long 都和指標同長。
作法二,把函式指標的位址轉型成 void * * 再指定。
fptr my_ptr = 0;
*reinterpret_cast< void * * >( &my_ptr ) = gptr;
...

2 則留言:

  1. 看了你這篇深有一個感覺,寫 C++ 大部分都在跟相容 C 奮鬥就是了 ..Orz

    回覆刪除
  2. C++ 把自己弄得太高級了 = =

    新一點的編譯器好像可以接受一次直接的 reinterpret_cast
    不過 static_cast 就沒辦法了

    回覆刪除