Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 从C风格指针访问self_Swift_Macos_Cocoa_Midi_Coremidi - Fatal编程技术网

Swift 从C风格指针访问self

Swift 从C风格指针访问self,swift,macos,cocoa,midi,coremidi,Swift,Macos,Cocoa,Midi,Coremidi,我正在开发一个使用MIDI设备的应用程序。在操场上玩了几次CoreMIDI之后,我发现了如何获取MIDI输入信号,因此我实现了以下功能: func makeInputSource() { var midiClient : MIDIClientRef = 0 var inPort : MIDIPortRef = 0 MIDIClientCreate("WobClient" as CFString, nil, nil, &midiClient) MIDIIn

我正在开发一个使用MIDI设备的应用程序。在操场上玩了几次CoreMIDI之后,我发现了如何获取MIDI输入信号,因此我实现了以下功能:

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)
}
但是,当我尝试这样做时,会出现以下错误:

A C function pointer cannot be formed from a closure that captures context
所以我想知道的是,有没有一种方法可以从闭包内部访问
self
,或者有没有其他方法可以在swift中使用MIDI输入

谢谢

---编辑: 如所问,修改后的代码:

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)

}
func makeInputSource(){
变量midiClient:MIDIClientRef=0
变量输入:MIDIPortRef=0
var observer=UnsafeRawPointer(Unmanaged.passUnretained(self.toOpaque())
midclientcreate(“WobClient”作为CFString、nil、nil和midclient)
MIDInputPortCreate(midiClient,“WobClient\u InPort”作为CFString{
(pktList:UnsafePointer,readprocurefcon:UnsafeMutableRawPointer?,srcconrefcon:UnsafeMutableRawPointer?)位于
let packetList:MIDIPacketList=pktList.pointee
var packet:MIDIPacket=packetList.packet
对于uu1…packetList.numPackets{
let bytes=Mirror(反射:packet.data).children
变量参数:[UInt64]=[]
var i=数据包长度
for(1;,attr),以字节为单位。枚举(){
让字符串=字符串(格式:“%02X”,属性值为!UInt8)
参数append(UInt64(strtoul(string,nil,16)))
i-=1

if(i通常可以将一些上下文传递到C函数中,例如:

struct MyContext {
   var setSliderValue: (Int) -> Void        
}

var context = MyContext(setSliderValue: { sliderValue in
    Dispatch.queue.async {
       self.slider_one?.integerValue = sliderValue
    }
))
然后将其传递给C函数:

MIDIInputPortCreate(midiClient, "WobClient_InPort" as CFString, { ... }, &context, &inPort)
let readContext = readProcRefCon!.assumingMemoryBound(to: MyContext.self)
readContext.pointee.setSliderValue(params[2])
在闭包函数中:

MIDIInputPortCreate(midiClient, "WobClient_InPort" as CFString, { ... }, &context, &inPort)
let readContext = readProcRefCon!.assumingMemoryBound(to: MyContext.self)
readContext.pointee.setSliderValue(params[2])

(未经测试编写)

通常可以将一些上下文传递到C函数中,例如:

struct MyContext {
   var setSliderValue: (Int) -> Void        
}

var context = MyContext(setSliderValue: { sliderValue in
    Dispatch.queue.async {
       self.slider_one?.integerValue = sliderValue
    }
))
然后将其传递给C函数:

MIDIInputPortCreate(midiClient, "WobClient_InPort" as CFString, { ... }, &context, &inPort)
let readContext = readProcRefCon!.assumingMemoryBound(to: MyContext.self)
readContext.pointee.setSliderValue(params[2])
在闭包函数中:

MIDIInputPortCreate(midiClient, "WobClient_InPort" as CFString, { ... }, &context, &inPort)
let readContext = readProcRefCon!.assumingMemoryBound(to: MyContext.self)
readContext.pointee.setSliderValue(params[2])

(未经测试而编写)

似乎是一个很棒的解决方案,但是,我如何才能从上下文变量访问
self
。@WesleyPeeters实际上,你可以将
self
作为上下文传递,或者你可以直接将其添加到
struct
。或者你可以将函数
getSelf
添加到
struct
。我的观点是你不需要传递
self
。相反,你可以传递一个已经封装了
self
的函数/闭包,就像我的
setSliderValue
那样。这似乎是一个很棒的解决方案,但是,我如何能够从上下文变量访问
self
e上下文,或者您可以直接将其添加到
struct
。或者您可以将一个函数
getSelf
添加到
struct
。我的观点是,通常您不需要传递
self
。相反,您可以传递一个已封装了
self
的函数/闭包,就像我的
setSliderValue
那样。这是ght也会有帮助:。@Martin尝试这样做:
UnsafeRawPointer(Unmanaged.passUnretained(self.toOpaque())
但是,我仍然会遇到同样的错误您不能在闭包中使用
self
,您必须从上下文指针重新构造它,请参见链接到答案中的
让我自己=非托管…
。我从未直接引用
self
,我使用了
让我自己=非托管…
,之后我尝试使用e> 我自己
variable@MartinR您能将修改后的代码添加到您的问题中吗?我很确定它能起作用。这可能也会有帮助:。@MartinR尝试这样做:
UnsafeRawPointer(Unmanaged.passUnretained(self.toOpaque())
但是,我仍然会遇到同样的错误您不能在闭包中使用
self
,您必须从上下文指针重新构造它,请参见链接到答案中的
让我自己=非托管…
。我从未直接引用
self
,我使用了
让我自己=非托管…
,之后我尝试使用e> 我自己variable@martinr您可以将修改后的代码添加到您的问题中吗?我相当肯定它是有效的。