Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass instance method as function pointer to C Library

I am writing an Objective-C application that uses a C Library. The issue which i am currently facing is that the C Library has a structure where some field are function pointers later used as callbacks. How can i convert an Objective-C instance method to a function pointer and pass it to the library?

like image 485
oipoistar Avatar asked Mar 01 '13 12:03

oipoistar


1 Answers

You will need to provide the C callback function within the Objective-C class implementation file, and this will only work if the callback is able to use a context pointer of some sort.

So imagine the C callback signature is like this:

void myCallback(void *context, int someOtherInfo);

Then within the Objective-C class implementation file you need to use that callback to trampoline back into your Objective-C class (using the context pointer as the instance of the class to invoke):

// Forward declaration of C callback function
static void theCallbackFunction(void *context, int someOtherInfo);

// Private Methods
@interface MyClass ()
- (void)_callbackWithInfo:(int)someOtherInfo;
@end

@implementation MyClass

- (void)methodToSetupCallback
{
    // Call function to set the callback function, passing it a "context"
    setCallbackFunction(theCallbackFunction, self);
    ...
}

- (void)_callbackWithInfo:(int)someOtherInfo
{
    NSLog(@"Some info: %d", someOtherInfo);
}

@end

static void theCallbackFunction(void *context, int someOtherInfo)
{
    MyClass *object = (MyClass *)context;
    [object _callbackWithInfo:someOtherInfo];
}

If your C callback function does not accept some sort of context info, then:

  1. It's broken and this should be fixed/reported as a bug.
  2. You will need to rely on storing a pointer-to-self at global, static, scope to be used by the C callback function. This will limit the number of instances of MyClass to one!
like image 58
trojanfoe Avatar answered Oct 22 '22 16:10

trojanfoe