簡體   English   中英

C編程:void *參數是它真正指向任何東西,我可以在那里傳遞函數指針

[英]C programming: void * argument is it really pointer to anything, can I pass function pointer there

我考慮如何正確使用void * (我從C語言中有一些突破)。 我記得void *用於啟用任何參數傳遞給回調函數。 我知道將原始類型int * ,const char *或甚至值集合作為struct attributes *傳遞是可以的。

我考慮將指向函數的指針傳遞給void *是否正常。

恩。

typedef void (*callback_t)(void *);
typedef void (*my_custom_callback_t)( /* list of params */ )

void someAPIFunction( /*... */, callback_t callback, void *callback_param);

void standard_callback(void *param) { 

       ((my_custom_callback_t) param) ( /* my params */ );
}

我考慮是否有這樣的類型將my_custom_callback作為param傳遞給standard_callback是正確的嗎?

void my_custom_callback(/* list of params */) { }

someAPIFunction( /*...*/, standard_callback, my_custom_callback); 

不,你不能將函數指針作為void *傳遞。

6.3.2.3指針

  1. 指向void的指針可以轉換為指向任何對象類型的指針。 指向任何對象類型的指針可以轉換為指向void的指針,然后再返回; 結果應該等於原始指針。

  1. 指向一種類型的函數的指針可以被轉換為指向另一種類型的函數的指針並且再次返回; 結果應該等於原始指針。 如果轉換的指針用於調用類型與引用類型不兼容的函數,則行為未定義。

注意沒有提到混合對象和函數指針的可能性。 它可能似乎適用於某些系統,但它是未定義的行為,並不能保證工作。

但是,您可以創建包裝器對象並傳遞該地址:

struct wrapper {
    my_custom_callback_t func;
};

struct wrapper my_wrapper = { my_custom_callback };
someAPIFunction( /*...*/, standard_callback, &my_wrapper); 

或者只是將指針傳遞給函數指針(函數指針變量是對象類型):

my_custom_callback_t func = my_custom_callback;
someAPIFunction( /*...*/, standard_callback, &func); 

事實上,大多數平台都允許您將函數指針作為void *傳遞,但理論上不允許這樣做。 代碼可能有不同的數據指針。 您也無法將const限定地址傳遞給void *。

正如已經指出的那樣,在一般情況下不允許這樣做,您可能會收到編譯器警告。 這是因為存在函數指針大於數據指針的平台。

然而,更常見的情況是指針大小確實相等。 用於訪問共享對象的接口dlsym()dlsym()GetProcAddress()實際上依賴GetProcAddress()

因此,如果您確定所有目標平台將使用與數據指針相同的函數指針大小,則可以通過首先轉換為例如uintptr_t使其顯式化(因此編譯器不會發出任何警告)。 所有指針類型都允許使用整數轉換, 只要整數足夠大以容納指針 ,定義良好。 uintptr_t保證足夠大以容納數據指針,因此如果函數指針的大小相同,那就沒問題了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM