【问题标题】:Obtaining a pointer to a class method so that it can be passed as a callback to a C function获取指向类方法的指针,以便可以将其作为回调传递给 C 函数
【发布时间】:2012-05-19 17:53:58
【问题描述】:

我正在使用 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()

【问题讨论】:

  • 好吧,总结一下,我说以下是否正确:在这种特定情况下,使用 IMP 将不起作用。 IMP 可用于其他需要签名要求不那么严格的 c 风格函数指针的情况?
  • 我认为这是一个很好的总结,是的。我要补充一点,您已经采用的方法是我在将 C 样式库与 Objective-C 程序集成时所做的。
  • 酷,感谢并感谢其他所有人的帮助。

标签: objective-c c function-pointers libssh2


【解决方案1】:

您现在采取的方法是合理的。也就是说,Objective-C 方法实际上只是 C 函数。使您建议的方法复杂化的主要原因是它们包含两个“隐藏”参数self_cmdself 是正在调用该方法的对象的实例,_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

【讨论】:

  • +1。由于 OP 询问了类方法,我会指出,对于那些 self 是类对象(即[SSHWrapper class])。
  • 谢谢肯。 OP 提到了一个类方法这一事实让我没有注意到。
  • 虽然我在吹毛求疵,但我会提到,如果 functionPointer 的类型仍然只是 IMP,那么您的演员阵容将无济于事。您需要正确输入以及进行演员表。
  • 感谢肯,它已修复。这就是我从头顶输入代码所得到的......
【解决方案2】:

没有。 + (void)method 创建的底层 C 函数不应以这种方式直接调用。除非你非常熟悉底层的 Objective-C 运行时,否则搞乱 IMP 函数只会给你带来麻烦。

【讨论】:

  • 我不同意。 IMP 并没有那么危险。您确实必须将它们转换为正确的函数指针类型以匹配方法的参数和返回类型,但就是这样。
  • 在这个例子中,它不起作用。在更一般的情况下,绕过消息传递系统可能会导致不同的行为。对于不熟悉消息传递方式的新手 Objective-C 开发人员,我不会推荐它。
猜你喜欢
  • 2012-10-22
  • 1970-01-01
  • 2017-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-17
相关资源
最近更新 更多