C 클래스 메소드에 대한 포인터를 획득하여 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
다른 팁
아니오.+ (void)method
가 생성하는 기본 C 함수는이 방식으로 직접 호출해서는 안됩니다.기본 Objective-C 런타임에 익숙하지 않은 한 Imp 함수를 망쳐 놓으면 문제가 발생합니다.