用Objective-C包装C库 - 功能指针

时间:2009-08-29 19:34:17

标签: c objective-c wrapper function-pointers

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

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

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

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

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

1 个答案:

答案 0 :(得分: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()作为结构返回类型)。