Wrapping a C Library with Objective-C - Function Pointers

允我心安 提交于 2019-12-03 20:08:31

Does register_callback_handler() also take a (void*) context argument? Most callback APIs do.

If it does, then you could use NSInvocation quite easily. Or you could allocate a little struct that contains a reference to the object and selector and then cobble up your own call.

If it only takes a function pointer, then you are potentially hosed. You need something somewhere that uniquely identifies the context, even for pure C coding.

Given that your callback handler does have a context pointer, you are all set:

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);

That is the general idea, anyway. If you need to deal with non-object typed arguments and/or callbacks, it gets a little bit trickier, but not that much. The easiest way is to call objc_msgSend() directly after typecasting it to a function pointer of the right type so the compiler generates the right call site (keeping in mind that you might need to use objc_msgSend_stret() for structure return types).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!