我正在Objective-C中编写一个围绕C库的包装器。该库允许我在发生某些事件时注册回调函数。
register_callback_handler()函数将函数指针作为参数之一。
我向您介绍编程大师的问题是:如何将Objective-C方法调用/选择器表示为函数指针?
任何帮助都会很棒,谢谢。
答案 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()作为结构返回类型)。