2017-01-25 2 views
2

J'ai une configuration de callback de lecture midi dans un projet Swift 3. Je voudrais garder le projet dans Swift entièrement sans avoir à recourir à l'objectif C juste pour faire ce travail. Il y a beaucoup d'articles sur Core Midi et Swift mais comme le framework change souvent, la syntaxe de ces articles ne s'applique plus.Le rappel de Core Midi Read n'est pas autorisé dans Swift 3

//Midi Message Callback 
func MIDIReadCallback (pktList :UnsafePointer<MIDIPacketList>, refCon :UnsafeMutableRawPointer?, srcConRef :UnsafeMutableRawPointer?) -> Void{ 

    let packet = pktList.pointee.packet 


    for _ in 0..<Int(pktList.pointee.numPackets) { 

     let mirrorData = Mirror(reflecting: packet.data) 

     var counter: UInt16 = 0 


     for(_, value)in mirrorData.children{ 

      let packetCount = packet.length 


      let n = value as! UInt8 

      let st = String(format: "%2X", n) 

      messageData.append(st) 

      counter += 1 

      if(value as! UInt8 == 247){ 
       processMidiMessage() 
       break} 

      if(packetCount == counter){break} 
     } 



    } 

} 

Je mets ce rappel lors de la création du port d'entrée comme celui-ci:

CheckError(error: MIDIInputPortCreate(client, "Input port" as CFString, MIDIReadCallback, &player, &inPort), 

Cela me donne l'exception suivante:

pointeur de fonction AC ne peut être formé à partir d'une référence à un 'func' ou une fermeture littérale

On ne sait pas très bien ce que cette exception signifie. La signature de la fonction correspond à la signature de rappel attendue et elle ressemble à une fonction Swift.

Que dois-je modifier pour que le compilateur accepte ma fonction Swift comme rappel de pointeur c?

+1

Le rappel ne peut pas être une méthode d'instance. Comparez http://stackoverflow.com/questions/33260808/how-to-use-instance-method-as-callback-for-function-which-takes-only-func-or-lit pour un problème similaire. –

Répondre

2

Un rappel CoreMIDI normal ne peut pas être une méthode d'instance, ou une fermeture qui utilise d'autres variables dans la portée, car elles doivent obéir à la sémantique @convention(c).

Cependant, dans CoreMIDI 1.3, vous pouvez utiliser MIDIInputPortCreateWithBlock à la place, ce qui prend un paramètre @escaping MIDIReadBlock au lieu d'un MIDIReadProc.