3 回答

TA貢獻1877條經(jīng)驗 獲得超1個贊
C標準不允許將函數(shù)指針轉(zhuǎn)換為void*。您只能轉(zhuǎn)換為其他函數(shù)指針類型。在C11標準6.3.2.3§8中:
指向一種類型的函數(shù)的指針可以轉(zhuǎn)換為指向另一種類型的函數(shù)的指針,然后再次返回
重要的是,在使用指針調(diào)用該函數(shù)之前,必須先強制轉(zhuǎn)換回原始類型(從技術(shù)上講,是兼容類型。在6.2.7中定義為“ compatible” )。
請注意,由于使用的上下文不同,許多(但不是全部)C編譯器也必須遵循POSIX標準,該標準要求可以將函數(shù)指針轉(zhuǎn)換為void*反向。這對于某些系統(tǒng)功能(例如dlsym)是必需的。

TA貢獻1811條經(jīng)驗 獲得超4個贊
不幸的是,該標準不允許在數(shù)據(jù)指針和函數(shù)指針之間進行強制轉(zhuǎn)換(因為在某些晦澀難懂的平臺上可能沒有意義),即使POSIX和其他平臺也需要強制轉(zhuǎn)換。一種解決方法不是強制轉(zhuǎn)換指針,而是強制將指針強制轉(zhuǎn)換為指針(編譯器可以這樣做,并且它將在所有普通平臺上完成工作)。
typedef void (*FPtr)(void); // Hide the ugliness
FPtr f = someFunc; // Function pointer to convert
void* ptr = *(void**)(&f); // Data pointer
FPtr f2 = *(FPtr*)(&ptr); // Function pointer restored

TA貢獻1820條經(jīng)驗 獲得超3個贊
關(guān)于數(shù)據(jù)指針和代碼指針,我有三個經(jīng)驗法則:
千萬不能混用數(shù)據(jù)指針和代碼指針
不要混用數(shù)據(jù)指針和代碼指針
永遠不要混合使用數(shù)據(jù)指針和代碼指針!
在以下功能中:
void setCallback(const void *fnPointer)
{
gfnPtr = *((FN_GET_VAL*) (&fnPointer));
}
您有一個指向函數(shù)指針的數(shù)據(jù)指針。(更不用說您通過首先獲取指針本身的地址,然后將其轉(zhuǎn)換為指向指針的指針,然后再取消對其引用)來執(zhí)行此操作。
嘗試將其重寫為:
void setCallback(FN_GET_VAL fnPointer)
{
gfnPtr = fnPointer;
}
另外,您可以(或應(yīng)該)在設(shè)置指針時放棄演員表:
main()
{
setCallback(myfunc);
gfnPtr();
}
另外,您現(xiàn)在可以使用編譯器執(zhí)行的常規(guī)類型檢查。
- 3 回答
- 0 關(guān)注
- 1045 瀏覽
添加回答
舉報