[英]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.