Swift 3 中不允许核心 Midi 读取回调

Core Midi Read callback not allowed in Swift 3

我在 Swift 3 项目中有一个 midi read proc 回调设置。我想将项目完全保留在 Swift 中,而不必为了完成这项工作而求助于 Objective C。有很多关于 Core Midi 和 Swift 的文章,但由于框架经常变化,这些文章中的语法不再适用。

    //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}
        }



    }

}

我在创建输入端口时放入了这个回调:

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

这给了我以下异常:

C 函数指针只能由对 'func' 或文字闭包的引用形成

我不清楚这个异常是什么意思。该函数的签名与预期的回调签名匹配,它看起来就像一个 Swift 函数。

我需要更改什么才能让编译器接受我的 Swift 函数作为正确的 c 指针回调?

普通的 CoreMIDI 回调不能是实例方法,也不能是使用范围内其他变量的闭包,因为它们必须遵守 @convention(c) 语义。

但是,在 CoreMIDI 1.3 中,您可以使用 MIDIInputPortCreateWithBlock,它采用 @escaping MIDIReadBlock 参数而不是 MIDIReadProc