簡體   English   中英

'void (*)(int)' 和 'void (^)(int)' 一樣嗎?

[英]Does 'void (*)(int)' the same with 'void (^)(int)'?

今天,我正在研究從 C++ 到 Objective-c 方法的回調傳遞。
最后,我解決了,但一些代碼讓我感到困惑。
在 Objective-c 中,人們通常使用 block 來實現回調,一個 block 聲明看起來像這樣:

returnType (^blockName)(parameterTypes)

我還了解了 C++ 回調,一個相同類型的回調定義如下:

returnType (*funcName)(parameterTypes)

當我將回調從 C++ 傳遞給 Objective-c 時,編譯器警告我:

"Cannot initialize a parameter of type 'void (^)(int)' with an rvalue of type 'void (*)(int)"

最后,我將^更改為* ,它起作用了。 我想知道, ^*在定義上有什么區別,它們的行為是否相同?

這是一個塊:

returnType (^blockName)(parameterTypes)

這是一個函數指針:

returnType (*funcName)(parameterTypes)

它們不兼容。

標准 C 和 C++ 沒有可調用塊。 然而,顯然,這些語言的一些編譯器確實將該功能作為擴展實現。 我看到的一些文檔表明它也是目標 C 的 Apple 擴展,但由於目標 C 在 Apple 世界之外很少使用,這可能是沒有區別的區別。

在任何語言中,如果您將回調實現為函數,那么您必須通過函數指針將該回調呈現給預期的調用者,並且調用者必須准備好以該形式接受它。 另一方面,如果您將回調實現為塊,那么您必須通過塊指針將其呈現給調用者,並且調用者必須准備好接受形式。 兩者不可互換,它們具有不同的語法,如您所見。 然而,通過單獨的參數或完全單獨的注冊函數,可以設計一種可以接受兩種形式的機制。

Objective-C 塊 ( ^ ) 與函數指針 ( * ) 不兼容。
與函數指針相比​​,它們的優點是能夠從周圍的上下文中捕獲值和變量(它們是閉包)。

編寫一個從塊調用函數指針的包裝器很容易:

typedef int (*funptr)(int);
typedef int (^funblock)(int);


int use_block_callback(int y, funblock fb)
{
    return fb(y);
}

int use_funptr_callback(int y, funptr f)
{
     return use_block_callback(y, ^ int (int x) { return f(x); }); 
}

int add_one(int x) { return x + 1; }

int foo(int x)
{
    return use_funptr_callback(23, add_one);
}

// Or
int (*some_pointer)(int) = add_one;
int (^some_block)(int) = ^ int (int x) { return some_pointer(x); } 

關於塊的“使用 Objective-C 編程”。

暫無
暫無

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

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