Обратный вызов Core Midi Read не разрешен в Swift 3
У меня есть настройка обратного вызова midi read proc в проекте Swift 3. Я хотел бы сохранить проект в 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),
Это дает мне следующее исключение:
Указатель на функцию A C может быть сформирован только из ссылки на "func" или буквального замыкания
Мне неясно, что означает это исключение. Сигнатура функции соответствует ожидаемой сигнатуре обратного вызова и выглядит как функция Swift.
Что мне нужно изменить, чтобы компилятор принял мою функцию Swift в качестве правильного обратного вызова указателя c?
1 ответ
Обычный обратный вызов CoreMIDI не может быть методом экземпляра или замыканием, использующим другие переменные в области видимости, поскольку они должны подчиняться @convention(c)
семантика.
Однако в CoreMIDI 1.3 вы можете использовать MIDIInputPortCreateWithBlock
вместо этого, который принимает @escaping MIDIReadBlock
параметр вместо MIDIReadProc
,