3

我正在用 Objective-C 编写一个 C 库的包装器。该库允许我在某些事件发生时注册回调函数。

register_callback_handler() 函数将函数指针作为参数之一。

我对编程大师的问题是:如何将 Objective-C 方法调用/选择器表示为函数指针?

  • NSInvocation 会在这种情况下有用还是级别太高?
  • 我最好只编写一个 C 函数,其中写有方法调用,然后将指针传递给该函数?

任何帮助都会很棒,谢谢。

4

1 回答 1

3

是否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() 来获取结构返回类型)。

于 2009-08-29T19:40:58.250 回答