我正在用 Objective-C 编写一个 C 库的包装器。该库允许我在某些事件发生时注册回调函数。
register_callback_handler() 函数将函数指针作为参数之一。
我对编程大师的问题是:如何将 Objective-C 方法调用/选择器表示为函数指针?
- NSInvocation 会在这种情况下有用还是级别太高?
- 我最好只编写一个 C 函数,其中写有方法调用,然后将指针传递给该函数?
任何帮助都会很棒,谢谢。
我正在用 Objective-C 编写一个 C 库的包装器。该库允许我在某些事件发生时注册回调函数。
register_callback_handler() 函数将函数指针作为参数之一。
我对编程大师的问题是:如何将 Objective-C 方法调用/选择器表示为函数指针?
任何帮助都会很棒,谢谢。
是否register_callback_handler()
也采用 (void*) 上下文参数?大多数回调 API 都可以。
如果是这样,那么您可以很容易地使用 NSInvocation。或者您可以分配一个包含对对象和选择器的引用的小结构,然后拼凑您自己的调用。
如果它只需要一个函数指针,那么你可能会被淹没。即使对于纯 C 编码,您也需要在某个地方唯一标识上下文的东西。
鉴于你的回调处理程序确实有一个上下文指针,你都准备好了:
typedef struct {
id target;
SEL selector;
// you could put more stuff here if you wanted
id someContextualSensitiveThing;
} TrampolineData;
void trampoline(void *freedata) {
TrampolineData *trampData = freedata;
[trampData->target performSelector: trampData->selector withObject: trampData-> someContextualSensitiveThing];
}
...
TrampolineData *td = malloc(sizeof(TrampolineData));
... fill in the struct here ...
register_callback_handler(..., trampoline, td);
无论如何,这是一般的想法。如果您需要处理非对象类型的参数和/或回调,它会变得有点棘手,但不是那么多。最简单的方法是在将 objc_msgSend() 类型转换为正确类型的函数指针后直接调用它,以便编译器生成正确的调用站点(请记住,您可能需要使用 objc_msgSend_stret() 来获取结构返回类型)。