gpt4 book ai didi

xcode - Swift 2 到 swift 3 转换 Midi 输入

转载 作者:可可西里 更新时间:2023-11-01 00:59:08 31 4
gpt4 key购买 nike

我希望有人可以帮助我使用 Xcode 8 和 swift 3我有一个 Playground 文件 Xcode 7 swift 2,它涉及 Midi 输入的 Midi 回调,在 7 中一切正常

我尝试转换为 8,它引发了关于内存的错误和一些我认为不严重的名称更改,我还使用 PlaygroundSupport 重新定义了无限循环但是我无法克服的错误涉及 MyMIDIReadProc at

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

错误说无法将类型“(pktList: UnsafePointer, readProcRefCon: UnsafeMutablePointer, srcConnRefCon: UnsafeMutablePointer) -> Void”的值转换为预期的参数类型“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

最佳答案

指针类型在 Swift 3 中发生了巨大变化。许多基于 C 的 API 的签名也相应地发生了变化。

手动执行这些更改会很痛苦。您可以让 Swift 为您工作,只需稍作修改。

尝试更改函数头:

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

闭包声明:

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

Swift 以这种方式完美地推断参数类型。

您可能需要修复指针类型转换:

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

像这样:

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

(顺便说一句,你的 Xcode 7 代码中的等效部分有点多余。你不需要在那里使用中间 COpaquePointer。)


在 Swift 3 中,指针不能为 nil,可空指针用 Optionals 表示。您可能需要许多其他修复才能在 Swift 3 中使用基于 C 的 API。

关于xcode - Swift 2 到 swift 3 转换 Midi 输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38258368/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com