2

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()ですか?

4

2 に答える 2

6

あなたが今取っているアプローチは合理的です。とは言うものの、Objective-Cメソッドは実際には単なるC関数です。あなたが提案するアプローチを複雑にする主なことは、それらが2つの「隠された」引数、、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

于 2012-05-19T18:08:22.330 に答える
-1

いいえ。によって作成される基になるC関数は+ (void)method、この方法で直接呼び出すべきではありません。基盤となるObjective-Cランタイムに精通していない限り、IMP関数をいじると問題が発生するだけです。

于 2012-05-19T18:14:36.123 に答える