2010-12-12 7 views
0

J'ai ce code dans un .mmTraduire en Objective-C de Objective-C++

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

qui va de pair avec cette ligne

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

puis le MyMIDINotifyProc est appelé à partir CoreMIDI.

Sans changer l'extension du fichier à .M, je traduit une signature Obj-C:

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

qui compile, mais je ne sais pas quoi faire avec la ligne MIDIClientCreate. Tel quel, il produit "MyMIDINotifyProc" was not declared in this scope. Il est censé être de type void * ... Et les docs sont 100% clair que c'est A refCon passed back to notifyRefCon (link).

Ce problème est-il résolu dans Obj-C seul? J'imagine que je devrais traduire le contenu C++ en C, auquel cas je le laisserais seul.

Répondre

3

MIDIClientCreate attend une fonction C ordinaire comme rappel. Vous ne pouvez pas passer une méthode Objective-C car la convention d'appel est différente (en C, les deux premiers paramètres d'une méthode Objective-C sont self et _cmd - le sélecteur - qui ne sera pas là pour une fonction C ordinaire).

La manière habituelle de contourner ceci est de créer une fonction C qui agit comme un shim et qui passe explicitement le self comme paramètre. La fonction shim envoie alors immédiatement le message objectif-C. Je ne suis pas familier avec cette bibliothèque, mais il semble que refCon est un paramètre conçu pour exactement ce genre de chose. Donc, dans votre fichier .m vous avez besoin d'une fonction comme celle-ci.

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

Vous devez également une méthode pour faire les choses réelles:

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

Et vous appelez MIDIClientCreate exactement comme vous le faisiez à l'origine.

+0

Merci, +1 et j'accepte cette réponse une fois que je l'ai digéré (ou une fois que XCode le fait;)). –