如何将回调函数从 C++ 传递到 Objective-C
How to pass a callback function from C++ to Objective-C
我不想使用 NSNotification,因为它在内部太混乱了。是否可以将回调函数从 C++ 传递给 Objective-C++,然后让 Objective-C 调用它?
问题是我不知道如何将用 C++ 编写的函数传递给 Objective-C++,我如何在 Objective-C++ 中使用该回调?是指针吗?
我知道我可以把它们混在一起,但我的 class 必须是 C++ class 因为它继承了一些 C++ classes.
对于您要在此处涵盖的确切用例,您并非 100% 具体,但我将列出发生这种情况的场景,然后向您展示如何解决它。我希望这也能解决你的问题。
所以我假设您有一个 Objective-C class MyClass
,其接口在 MyClass.h 中声明:
@interface MyClass : NSObject
- (void)someMethod;
- (void)otherMethodWhichShouldTakeACallback:?????;
@end
您现在有一个 C++ class MyCPPClass
,在 MyCPPClass.hpp 中声明,您希望在其上传递 memberFunction
作为MyClass
:
上 otherMethod
的回调参数
class MyCPPClass : public MyBase
{
void memberFunction();
};
首先,我们需要弄清楚MyClass
上的方法签名。 Objective-C 中回调的现代方式是使用 Blocks。块与 Objective-C++ 一起工作得很好,所以让我们继续并使用以下行修改 MyClass.h
:
- (void)otherMethodWithBlock:(void(^)(void))callbackBlock;
调用代码需要驻留在Objective-C++编译单元中(caller.mm):
void callOtherMemberWithCPP(MyCPPClass* cpp_obj, MyClass* objc_obj)
{
[objc_obj otherMethodWithBlock:^{
cpp_obj->memberFunction();
}];
}
请注意,这不涉及对象生命周期。如果你在 C++ 端使用 std::shared_ptr
管理生命周期,你也可以在你的 Objective-C++ 代码中使用它,在这种情况下,我们可能会得到如下结果:
void callOtherMemberWithCPP(std::shared_ptr<MyCPPClass> cpp_obj, MyClass* objc_obj)
{
[objc_obj otherMethodWithBlock:^{
cpp_obj->memberFunction();
}];
}
在这种情况下,C++ 对象的引用计数只会在 Objective-C class 完成该块时减少。
为了完整起见,另一种方法是使用 C 函数指针语法。在这种情况下,您需要按照以下行声明 Objective-C 方法:
- (void)otherMethodWithCallback:(void(*)(void*))callback object:(void*)opaqueCallbackArgument;
并且 C++ class 的方法调用需要包装在自由函数或静态成员函数中:
void memberFunctionCallback(void* opaque_object)
{
MyCPPClass* object = static_cast<MyCPPClass*>(opaque_object);
object->memberFunction
}
…然后像这样调用Objective-C方法:
[objc_obj otherMethodWithCallback:memberFunctionCallback object:cpp_obj];
不过,要使此版本与 shared_ptr
等自动生命周期机制配合得很好,要棘手得多。
我不想使用 NSNotification,因为它在内部太混乱了。是否可以将回调函数从 C++ 传递给 Objective-C++,然后让 Objective-C 调用它?
问题是我不知道如何将用 C++ 编写的函数传递给 Objective-C++,我如何在 Objective-C++ 中使用该回调?是指针吗?
我知道我可以把它们混在一起,但我的 class 必须是 C++ class 因为它继承了一些 C++ classes.
对于您要在此处涵盖的确切用例,您并非 100% 具体,但我将列出发生这种情况的场景,然后向您展示如何解决它。我希望这也能解决你的问题。
所以我假设您有一个 Objective-C class MyClass
,其接口在 MyClass.h 中声明:
@interface MyClass : NSObject
- (void)someMethod;
- (void)otherMethodWhichShouldTakeACallback:?????;
@end
您现在有一个 C++ class MyCPPClass
,在 MyCPPClass.hpp 中声明,您希望在其上传递 memberFunction
作为MyClass
:
otherMethod
的回调参数
class MyCPPClass : public MyBase
{
void memberFunction();
};
首先,我们需要弄清楚MyClass
上的方法签名。 Objective-C 中回调的现代方式是使用 Blocks。块与 Objective-C++ 一起工作得很好,所以让我们继续并使用以下行修改 MyClass.h
:
- (void)otherMethodWithBlock:(void(^)(void))callbackBlock;
调用代码需要驻留在Objective-C++编译单元中(caller.mm):
void callOtherMemberWithCPP(MyCPPClass* cpp_obj, MyClass* objc_obj)
{
[objc_obj otherMethodWithBlock:^{
cpp_obj->memberFunction();
}];
}
请注意,这不涉及对象生命周期。如果你在 C++ 端使用 std::shared_ptr
管理生命周期,你也可以在你的 Objective-C++ 代码中使用它,在这种情况下,我们可能会得到如下结果:
void callOtherMemberWithCPP(std::shared_ptr<MyCPPClass> cpp_obj, MyClass* objc_obj)
{
[objc_obj otherMethodWithBlock:^{
cpp_obj->memberFunction();
}];
}
在这种情况下,C++ 对象的引用计数只会在 Objective-C class 完成该块时减少。
为了完整起见,另一种方法是使用 C 函数指针语法。在这种情况下,您需要按照以下行声明 Objective-C 方法:
- (void)otherMethodWithCallback:(void(*)(void*))callback object:(void*)opaqueCallbackArgument;
并且 C++ class 的方法调用需要包装在自由函数或静态成员函数中:
void memberFunctionCallback(void* opaque_object)
{
MyCPPClass* object = static_cast<MyCPPClass*>(opaque_object);
object->memberFunction
}
…然后像这样调用Objective-C方法:
[objc_obj otherMethodWithCallback:memberFunctionCallback object:cpp_obj];
不过,要使此版本与 shared_ptr
等自动生命周期机制配合得很好,要棘手得多。