我在Swift 3项目中有一个midi read proc回调设置。我想完全保留Swift中的项目,而不必仅仅为了使这项工作成为目标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函数指针只能通过对“函数”的引用形成。或文字封闭
我不清楚这个例外意味着什么。函数的签名与预期的回调签名匹配,它看起来就像一个Swift函数。
我需要更改什么才能使编译器接受我的Swift函数作为正确的c指针回调?
答案 0 :(得分:2)
普通的CoreMIDI回调不能是实例方法,也不能是使用范围内其他变量的闭包,因为它们必须遵守@convention(c)
语义。
但是,在CoreMIDI 1.3中,您可以使用MIDIInputPortCreateWithBlock
代替@escaping MIDIReadBlock
参数而不是MIDIReadProc
。