0

私はこのコードを.mmに持っています

void MyMIDINotifyProc(const MIDINotification *message, void *refCon);

これはこの行に一致します

MIDIClientCreate((CFStringRef)@"MidiMonitor MIDI Client", MyMIDINotifyProc, self, &client);

次に、MyMIDINotifyProcがCoreMIDIから呼び出されます。

ファイル拡張子を.mに変更せずに、Obj-C署名に変換しました。

@interface MidiInput (Private) 
    -(void) MyMIDINotifyProc:(const MIDINotification *)message reference:(void *)refCon;
@end

これはコンパイルされますが、その行をどうするかわかりませんMIDIClientCreate。そのまま、を生成し"MyMIDINotifyProc" was not declared in this scopeます。それはタイプであると思われますvoid *...そしてドキュメントはそれがA refCon passed back to notifyRefConリンク)であることを100%明確にしています。

この問題はObj-Cだけで解決できますか?C ++のものをCに変換する必要があると思います。その場合は、そのままにしておきます。

4

1 に答える 1

3

MIDIClientCreateコールバックとして通常の C 関数が必要です。呼び出し規則が異なるため、Objective-C メソッドに渡すことはできません (C の用語では、Objective-C メソッドへの最初の 2 つのパラメーターはself_cmdセレクターであり、通常の C 関数にはありません)。

これを回避する通常の方法は、シムとして機能する C 関数を作成し、self をパラメーターとして明示的に渡すことです。shim 関数はすぐに Objective-C メッセージを送信します。私はこのライブラリに精通していませんがrefCon、まさにこの種のもののために設計されたパラメーターのようです。したがって、.mファイルにはこのような関数が必要です。

static void MyMIDINotifyProc(const MIDINotification *message, void *refCon)
{
    [(id) refCon MIDINotify: message];
}

実際の処理を行うメソッドも必要です。

-(void) MIDINotify: (const MIDINotification*) message
{
    // do stuff
}

そして、最初に行っていたのとまったく同じように MIDIClientCreate を呼び出します。

于 2010-12-12T19:11:43.287 に答える