Метод экземпляра Pass как функция указателя на C Library

Я пишу приложение Objective-C, которое использует C-библиотеку. Проблема, с которой я сейчас сталкиваюсь, заключается в том, что C Library имеет структуру, в которой какое-то поле является указателем на функции, позже используемым в качестве обратных вызовов. Как преобразовать метод экземпляра Objective-C в указатель функции и передать его в библиотеку?

Ответы

Ответ 1

Вам нужно будет предоставить функцию обратного вызова C в файле реализации класса Objective-C, и это будет работать только в том случае, если обратный вызов может использовать какой-либо указатель контекста.

Итак, представьте, что C-обратная подпись выглядит так:

void myCallback(void *context, int someOtherInfo);

Затем в файле реализации класса Objective-C вам необходимо использовать этот обратный вызов для трамплина обратно в ваш класс Objective-C (используя указатель контекста в качестве экземпляра вызываемого класса):

// 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];
}

Если ваша функция обратного вызова C не принимает какую-либо информацию контекста, то:

  • Он сломан, и это должно быть исправлено/сообщено как ошибка.
  • Вам нужно будет полагаться на сохранение указателя к себе в глобальной, статической области, используемой функцией обратного вызова C. Это ограничит количество экземпляров MyClass до одного!