简体   繁体   English

'void (*)(int)' 和 'void (^)(int)' 一样吗?

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

Today, I'm working on a callback pass from C++ to Objective-c method.今天,我正在研究从 C++ 到 Objective-c 方法的回调传递。
Finally, I worked it out, but a few code confuse me.最后,我解决了,但一些代码让我感到困惑。
In Objective-c, people ordinary use block to implement a callback, a block declare looks like this:在 Objective-c 中,人们通常使用 block 来实现回调,一个 block 声明看起来像这样:

returnType (^blockName)(parameterTypes) returnType (^blockName)(parameterTypes)

I also learned about C++ callback, a same type callback defined like this:我还了解了 C++ 回调,一个相同类型的回调定义如下:

returnType (*funcName)(parameterTypes) returnType (*funcName)(parameterTypes)

When I passed a callback from C++ to Objective-c, compiler warning me:当我将回调从 C++ 传递给 Objective-c 时,编译器警告我:

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

Finally, I changed ^ to * , it works.最后,我将^更改为* ,它起作用了。 I wondering to know, what's the difference between ^ and * in definition, is that have the same behavior?我想知道, ^*在定义上有什么区别,它们的行为是否相同?

This is a block:这是一个块:

returnType (^blockName)(parameterTypes)

This is a function pointer:这是一个函数指针:

returnType (*funcName)(parameterTypes)

They aren't compatible.它们不兼容。

Standard C and C++ do not have callable blocks.标准 C 和 C++ 没有可调用块。 Apparently, however, some compilers for those languages do implement the feature as an extension.然而,显然,这些语言的一些编译器确实将该功能作为扩展实现。 Some of the docs I see suggest that it's an Apple extension to Objective C, too, but inasmuch as Objective C is little used outside the Apple world, that may be a distinction without a difference.我看到的一些文档表明它也是目标 C 的 Apple 扩展,但由于目标 C 在 Apple 世界之外很少使用,这可能是没有区别的区别。

In whatever language, if you implement a callback as a function, then you must present that callback to the intended caller via a function pointer, and the caller must be prepared to accept it in that form.在任何语言中,如果您将回调实现为函数,那么您必须通过函数指针将该回调呈现给预期的调用者,并且调用者必须准备好以该形式接受它。 On the other hand, if you implement a callback as a block then you must present it to the caller via a block pointer, and the caller must be prepared to accept that form.另一方面,如果您将回调实现为块,那么您必须通过块指针将其呈现给调用者,并且调用者必须准备好接受形式。 The two are not interchangeable, and they have different syntaxes, which you have presented.两者不可互换,它们具有不同的语法,如您所见。 It would be possible to design a mechanism that could accept both forms, however, via separate parameters or altogether separate registration functions.然而,通过单独的参数或完全单独的注册函数,可以设计一种可以接受两种形式的机制。

Objective-C blocks ( ^ ) are incompatible with function pointers ( * ). Objective-C 块 ( ^ ) 与函数指针 ( * ) 不兼容。
Compared to function pointers, they have the benefit of being able to capture values and variables from the surrounding context (they are closures ).与函数指针相比​​,它们的优点是能够从周围的上下文中捕获值和变量(它们是闭包)。

It's easy enough to write a wrapper that calls a function pointer from a block:编写一个从块调用函数指针的包装器很容易:

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); } 

( "Programming with Objective-C" about blocks. ) 关于块的“使用 Objective-C 编程”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM