Получение указателя на метод класса, чтобы его можно было передать в качестве обратного вызова функции C.
-
11-12-2019 - |
Вопрос
Я использую libssh2, и у меня есть функция обратного вызова, определенная вне моего объекта SSHWrapper:
static void kbd_callback(const char *name, int name_len, const char *instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract);
Из моего объекта SSHWrapper я делаю следующее, передавая функцию обратного вызова при аутентификации сеанса:
/* Create a session instance */
LIBSSH2_SESSION *session = libssh2_session_init_ex(NULL, NULL, NULL, self);
while ((rc = libssh2_userauth_keyboard_interactive(session, userChar, &kbd_callback)) == LIBSSH2_ERROR_EAGAIN);
Меня интересует, можно ли переместить kbd_callback()
функция внутри моего объекта, так что это метод класса: +(void) kbd_callback:...
?
Если да, то как мне получить адрес этой функции, чтобы передать его функции C? libssh2_userauth_keyboard_interactive()
?
Решение
Подход, который вы сейчас применяете, разумен.Тем не менее, методы Objective-C на самом деле являются просто функциями C.Главное, что усложняет предлагаемый вами подход, это то, что он включает два «скрытых» аргумента: self
, и _cmd
. self
это экземпляр объекта, для которого вызывается метод, и _cmd
является селектором метода.Вы не можете их изменить, и их присутствие сделает невозможным соответствие аргументов вашей функции аргументам, необходимым для функции обратного вызова.
На всякий случай, если вам это все еще интересно, вы можете получить указатель функции на метод Objective-C следующим образом:
IMP methodIMP = [self methodForSelector:@selector(someMethodThatTakesOneStringArgument:)];
void (*functionPointer)(id, SEL, NSString*) = (void (*)(id, SEL, NSString*))methodIMP;
// Then call it:
functionPointer(instance, @selector(someMethodThatTakesOneStringArgument:), aString);
РЕДАКТИРОВАТЬ:Я разместил здесь простую и полную программу, демонстрирующую этот код в действии: https://gist.github.com/2731937
Другие советы
Нет.Базовая функция C, которая создается + (void)method
не следует вызывать напрямую таким образом.Если вы не очень хорошо знакомы с базовой средой выполнения Objective-C, вмешательство в функции IMP приведет только к неприятностям.