Принимает ли 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() для типов возвращаемых структур).
person
bbum
schedule
29.08.2009