I'm writing a wrapper around a C library in Objective-C. The library allows me to register callback functions when certain events occur.
The register_callback_handler() function takes a function pointer as one of the parameters.
My question to you gurus of programming is this: How can I represent an Objective-C method call / selector as a function pointer?
- Would NSInvocation be something useful in this situation or too high level?
- Would I be better off just writing a C function that has the method call written inside it, and then pass the pointer to that function?
Any help would be great, thanks.
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).