Получение указателя на метод класса, чтобы его можно было передать в качестве обратного вызова функции C.

StackOverflow https://stackoverflow.com//questions/10667587

Вопрос

Я использую 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 приведет только к неприятностям.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top