我有一個由dlsym()返回的void指針,我想調用void指針指向的函數。 所以我做一個類型轉換通過鑄造:函數指針在C++中鑄造
void *gptr = dlsym(some symbol..) ;
typedef void (*fptr)();
fptr my_fptr = static_cast<fptr>(gptr) ;
我也曾嘗試reinterpret_cast
,但沒有運氣,雖然C轉換運算符似乎工作..
我有一個由dlsym()返回的void指針,我想調用void指針指向的函數。 所以我做一個類型轉換通過鑄造:函數指針在C++中鑄造
void *gptr = dlsym(some symbol..) ;
typedef void (*fptr)();
fptr my_fptr = static_cast<fptr>(gptr) ;
我也曾嘗試reinterpret_cast
,但沒有運氣,雖然C轉換運算符似乎工作..
轉換一個void*
一個函數指針直接在C++ 98/03中是不允許的(不應該使用任何強制轉換)。它有條件地支持C++ 0x(一個實現可以選擇定義行爲,如果它確實定義了它,那麼它必須執行標準所說的它應該做的事情。由C++ 98/03標準定義的一個void*
,是爲了指向對象,而不是包含函數指針或成員指針。
知道你在做什麼很大程度上依賴於實現,這裏有一個選項應該是編譯和工作的(假設32位指針,使用long long對於64位)在大多數平臺上,即使它顯然是根據標準定義的操作:
void *gptr = dlsym(some symbol..) ;
typedef void (*fptr)();
fptr my_fptr = reinterpret_cast<fptr>(reinterpret_cast<long>(gptr)) ;
這裏是應該編譯和工作,但卡爾另一種選擇它IES相同的警告如上述:
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 casting正在向後兼容POSIX共享庫調用的要求。 – 2009-07-08 06:16:19
這可能對你有所幫助。它打印「你好」。
#include <iostream>
void hello()
{
std::cout << "Hello" << std::endl;
}
int main() {
typedef void (*fptr)();
fptr gptr = (fptr) (void *) &hello;
gptr();
}
或者你可以這樣做:
fptr gptr = reinterpret_cast<fptr>((void *) &hello);
其中&你好通過對dlsym命令取代。
這將編譯在Visual Studio中不使用重新詮釋投:
void *ptr;
int (*func)(void) = (int(*)(void))ptr;
int num = func();
,我發現這個(有點難看)解決方案。具有最大警告級別的gcc不會抱怨。 本示例調用dlsym()(返回void *)並將結果返回給函數指針。
typedef void (*FUNPTR)();
FUNPTR fun_dlsym(void* handle, const char* name) {
union {
void* ptr;
FUNPTR fptr;
} u;
u.ptr = dlsym(handle, name);
return u.fptr;
}
注意,C++ 11允許從GCC 4.9這樣的轉換和和高於此轉換不產生警告:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57869。
看到這麼討論:
哎,你的格式有陷入困境。 – 2009-07-08 06:11:19
您確實需要修正該代碼,以便我們可以閱讀它。什麼是反斜槓?您是否嘗試輸入my_fptr = static_cast(gptr)? –
2009-07-08 06:11:41
修復了格式問題。而不是使用HTML標記,請使用可用的格式化按鈕。 – Naveen 2009-07-08 06:14:13