Je travaille sur une application qui utilise un équipement MIDI. Après quelques niaisage dans une aire de jeux avec CoreMIDI, j'ai trouvé comment obtenir le signal d'entrée MIDI, donc je mis en œuvre cette:Accès à partir d'un pointeur de style C
func makeInputSource() {
var midiClient : MIDIClientRef = 0
var inPort : MIDIPortRef = 0
MIDIClientCreate("WobClient" as CFString, nil, nil, &midiClient)
MIDIInputPortCreate(midiClient, "WobClient_InPort" as CFString, {
(pktList: UnsafePointer<MIDIPacketList>, readProcRefCon: UnsafeMutableRawPointer?, srcConnRefCon: UnsafeMutableRawPointer?) in
let packetList : MIDIPacketList = pktList.pointee
var packet : MIDIPacket = packetList.packet
for _ in 1...packetList.numPackets {
let bytes = Mirror(reflecting: packet.data).children
var params : [UInt64] = []
var i = packet.length
for (_, attr) in bytes.enumerated() {
let string = String(format: "%02X ", attr.value as! UInt8)
params.append(UInt64(strtoul(string, nil, 16)))
i -= 1
if (i <= 0) {
break
}
}
packet = MIDIPacketNext(&packet).pointee
}
}, nil, &inPort)
MIDIPortConnectSource(inPort, self.source, &self.source)
}
Ce qui fonctionne comme un charme pour utiliser le signal. Maintenant, je veux utiliser le signal pour modifier la valeur d'un NSSlider
, donc, naturellement, ce que je suis venu avec était la suivante:
self.slider_one?.integerValue = params[2]
Cependant, lorsque je tente de le faire, je reçois l'erreur suivante:
A C function pointer cannot be formed from a closure that captures context
donc ce que je me demande est-il un moyen d'accéder self
à l'intérieur de cette fermeture, ou est-il une autre façon d'utiliser l'entrée MIDI rapide?
Merci.
--- Edit: Comme demandé, mon code après modification:
func makeInputSource() {
var midiClient : MIDIClientRef = 0
var inPort : MIDIPortRef = 0
var observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())
MIDIClientCreate("WobClient" as CFString, nil, nil, &midiClient)
MIDIInputPortCreate(midiClient, "WobClient_InPort" as CFString, {
(pktList: UnsafePointer<MIDIPacketList>, readProcRefCon: UnsafeMutableRawPointer?, srcConnRefCon: UnsafeMutableRawPointer?) in
let packetList : MIDIPacketList = pktList.pointee
var packet : MIDIPacket = packetList.packet
for _ in 1...packetList.numPackets {
let bytes = Mirror(reflecting: packet.data).children
var params : [UInt64] = []
var i = packet.length
for (_, attr) in bytes.enumerated() {
let string = String(format: "%02X ", attr.value as! UInt8)
params.append(UInt64(strtoul(string, nil, 16)))
i -= 1
if (i <= 0) {
break
}
}
let mySelf = Unmanaged<Wob>.fromOpaque(observer).takeUnretainedValue()
mySelf.slider_one?.integerValue = 25 // 25 is a test value
packet = MIDIPacketNext(&packet).pointee
}
}, &observer, &inPort)
MIDIPortConnectSource(inPort, self.source, &self.source)
}
Cela pourrait aussi être utile: [Comment utiliser la méthode de l'instance comme rappel pour la fonction qui ne prend que la fermeture ou func littérale] (http://stackoverflow.com/questions/33260808/how-to-use-instance-method-as-callback-for-function-which-takes-only-func-ou-allumé). –
@MartinR J'ai essayé de faire comme ceci: 'UnsafeRawPointer (Unmanaged.passUnretained (self) .toOpaque())' Cependant, je reçois toujours la même erreur –
Vous ne devez pas utiliser 'self' dans la fermeture, vous devez le reconstruire à partir du pointeur de contexte, voir 'let mySelf = Unmanaged ...' dans la réponse liée. –