2016-07-08 14 views
0

誰かが私がXcode 8とスウィフト3を使用しているのを助けることができると願っています 私はMidi Input用のMidiコールバックを含むプレイグラウンドファイルXcode 7 swift 2を持っています罰金は7スウィフト2からスウィフト3への変換ミディ入力

に私は8への変換を試み、それがメモリに関するエラーを育て、いくつかの名前は、私はエラーが私は乗り越えることができないしかし、私はまたPlaygroundSupport を使用して無限ループを再定義非深刻であると信じるものの大部分は変更しますMyMIDIReadProcは、

にあります。
MIDIInputPortCreate(midiClient, "MidiTest_InPort", MyMIDIReadProc, nil, &inPort); 

エラーはと表示されています(UnsafePointer、UnsafeMutablePointer、srcConnRefCon:UnsafeMutablePointer) - >無効な引数型 'MIDIReadProc'(別名@convention(c)(UnsafePointer、Optional>、Optional>) - >型の値を変換できません。 () ')

@convention(c)ラッパーに何らかの記述を挿入する必要があると私は理解しています。私はあなたが関数をラップすることができるので私は正しい軌道にいると思うが、それを置くための私の知識がなくなった。ここでも私は自分がここ

は、元のXcode 7コード

  import Cocoa 
      import CoreMIDI 
      import XCPlayground 

      func getDisplayName(obj: MIDIObjectRef) -> String 
      { 
       var param: Unmanaged<CFString>? 
       var name: String = "Error"; 

       let err: OSStatus = MIDIObjectGetStringProperty(obj, kMIDIPropertyDisplayName, &param) 
       if err == OSStatus(noErr) 
       { 
        name = param!.takeRetainedValue() as String 
       } 

       return name; 
      } 

      func MyMIDIReadProc(pktList: UnsafePointer<MIDIPacketList>, 
       readProcRefCon: UnsafeMutablePointer<Void>, srcConnRefCon: UnsafeMutablePointer<Void>) -> Void 
      { 
       let packetList:MIDIPacketList = pktList.memory; 
       let srcRef:MIDIEndpointRef = UnsafeMutablePointer<MIDIEndpointRef>(COpaquePointer(srcConnRefCon)).memory; 
       print("MIDI Received From Source: \(getDisplayName(srcRef))"); 

       var packet:MIDIPacket = packetList.packet; 
       for _ in 1...packetList.numPackets 
       { 
        let bytes = Mirror(reflecting: packet.data).children; 
        var dumpStr = ""; 
        // bytes mirror contains all the zero values in the ridiulous packet data tuple 
        // so use the packet length to iterate. 
        var i = packet.length; 
        for (_, attr) in bytes.enumerate() 
        { 
         dumpStr += String(format:"$%02X ", attr.value as! UInt8); 
         --i; 
         if (i <= 0) 
         { 
          break; 
         } 
        } 

        print(dumpStr) 
        packet = MIDIPacketNext(&packet).memory; 
       } 
      } 

      var midiClient: MIDIClientRef = 0; 
      var inPort:MIDIPortRef = 0; 
      var src:MIDIEndpointRef = MIDIGetSource(0); 

      MIDIClientCreate("MidiTestClient", nil, nil, &midiClient); 
      MIDIInputPortCreate(midiClient, "MidiTest_InPort", MyMIDIReadProc, nil, &inPort); 

      MIDIPortConnectSource(inPort, src, &src); 

      // Keep playground running 
      XCPlaygroundPage.currentPage.needsIndefiniteExecution = true; 

そして、ここで教えてるとしていくつかのいずれかが任意の悪い言語用 謝罪を読み取るための

感謝を助言することができるかもしれません期待していましたは、Xcode 8コードを変換したものです。

  var str = "Hello, playground" 
      import Cocoa 
      import CoreMIDI 
      import XCPlayground 
      import PlaygroundSupport 


      func getDisplayName(obj: MIDIObjectRef) -> String 
      { 
      var param: Unmanaged<CFString>? 
      var name: String = "Error"; 

      let err: OSStatus = MIDIObjectGetStringProperty(obj, kMIDIPropertyDisplayName, &param) 
      if err == OSStatus(noErr) 
      { 
      name = param!.takeRetainedValue() as String 
      } 

      return name; 
      } 


      func MyMIDIReadProc(pktList: UnsafePointer<MIDIPacketList>, 
           readProcRefCon: UnsafeMutablePointer<Void>, srcConnRefCon: UnsafeMutablePointer<Void>) -> Void 
      { 


      let packetList:MIDIPacketList = pktList.pointee; 

      let srcRef:MIDIEndpointRef = UnsafeMutablePointer<MIDIEndpointRef>(OpaquePointer(srcConnRefCon)).pointee; 
      print("MIDI Received From Source: \(getDisplayName(obj: srcRef))"); 

      var packet:MIDIPacket = packetList.packet; 
      for _ in 1...packetList.numPackets 
      { 
      let bytes = Mirror(reflecting: packet.data).children; 
      var dumpStr = ""; 

      var i = packet.length; 
      for (_, attr) in bytes.enumerated() 
      { 
      dumpStr += String(format:"$%02X ", attr.value as! UInt8); 
      i -= 1; 
      if (i <= 0) 
      { 
      break; 
      } 

      } 

      print(dumpStr) 
      packet = MIDIPacketNext(&packet).pointee; 
      } 
      } 

      var midiClient: MIDIClientRef = 0; 
      var inPort:MIDIPortRef = 0; 
      var src:MIDIEndpointRef = MIDIGetSource(0); 

      MIDIClientCreate("MidiTestClient", nil, nil, &midiClient); 

      MIDIInputPortCreate(midiClient, "MidiTest_InPort", MyMIDIReadProc, nil, &inPort); 

      MIDIPortConnectSource(inPort, src, &src); 


      PlaygroundPage.current.needsIndefiniteExecution = true 

答えて

1

Swift 3ではポインタ型が大幅に変更されています。多くのCベースのAPIの署名はそれに応じて変更されています。

これらの変更を手動で行うことは苦痛になります。ちょっとした改造を加えて、Swiftをあなたのために動かすことができます。閉鎖宣言に

func MyMIDIReadProc(pktList: UnsafePointer<MIDIPacketList>, 
           readProcRefCon: UnsafeMutablePointer<Void>, srcConnRefCon: UnsafeMutablePointer<Void>) -> Void 
      { 

は、関数のヘッダーを変更してみてください

let MyMIDIReadProc: MIDIReadProc = {pktList, readProcRefCon, srcConnRefCon in 

スウィフトはこのスタイルで完璧に引数の型を推論します。

あなたはポインタ型変換修正する必要があります(ちなみに、あなたのXcode 7のコードで同等の部分が少し冗長である

//I'm not sure using `!` is safe here... 
    let srcRef: MIDIEndpointRef = UnsafeMutablePointer(srcConnRefCon!).pointee 

:このような何かに

let srcRef:MIDIEndpointRef = UnsafeMutablePointer<MIDIEndpointRef>(OpaquePointer(srcConnRefCon)).pointee; 

を)


スウィフト3では、ポインタNULLにすることはできません。また、null可能なポインタは、Optionalsで表されます。 Swift 3でCベースのAPIを使用するには、他にも多くの修正が必要な場合があります。

0

OOPerは正しい方向を指しています。ここには、Swift 3 Core MIDIとgithubリポジトリを使用したブログ記事があります。

0

CoreMIDI 1.3以降で作業していると仮定すると、MIDIInputPortCreateの代わりにMIDIInputPortCreateWithBlockを使用すると運が増える可能性があります。

public func midiReadBlock(ptr: UnsafePointer<MIDIPacketList>, _: UnsafeMutableRawPointer?) -> Void { 
    let list: MIDIPacketList = ptr.pointee 
    ... 
} 

またこれらの2つの拡張を見つけることがあります。

この方法は、例えば、スウィフトクラスに属するメソッド内で使用することがより容易作り、代わりに@convention(c)関数参照を必要とするパラメータとしてスウィフトブロックを取ります有用。

here由来)この1つはあなたがfor pkt in listを使用MIDIPacketList上に直接反復することができ:

extension MIDIPacketList: Sequence { 

    public func makeIterator() -> AnyIterator<MIDIPacket> { 
     var iterator: MIDIPacket? 
     var nextIndex: UInt32 = 0 

     return AnyIterator { 
      nextIndex += 1 
      if nextIndex > self.numPackets { return nil } 
      if iterator != nil { 
       iterator = withUnsafePointer(to: &iterator!) { MIDIPacketNext($0).pointee } 
      } else { 
       iterator = self.packet; 
      } 
      return iterator 
     } 
    } 
} 

及びこれを使用することの代わり[UInt8]としてコンテンツを抽出するMIDIPacketにメソッドを追加実際に破られたタプル構文:

extension MIDIPacket { 
    public var asArray: [UInt8] { 
     let mirror = Mirror(reflecting: self.data) 
     let length = Int(self.length) 

     var result = [UInt8]() 
     result.reserveCapacity(length) 

     for (n, child) in mirror.children.enumerated() { 
      if n == length { 
       break 
      } 
      result.append(child.value as! UInt8) 
     } 
     return result 
    } 
} 
関連する問題