一尘不染

使用Swift CFunctionPointer将回调传递给CoreMIDI API

swift

可能这实际上是当前不可能的,这很不幸。我正在尝试调用CoreMIDI API来设置MIDI输入。这就是我要在Swift中执行的操作:

var midiClient = MIDIClientRef()
var inputPort = MIDIEndpointRef()
var status: OSStatus

func readProc(packetList: UnsafePointer<MIDIPacketList>, readProcRefCon: UnsafeMutablePointer<Void>, srcConnRefCon: UnsafeMutablePointer<Void>) -> Void {
}

status = MIDIClientCreate("MIDI client", nil, nil, &midiClient);

status = MIDIDestinationCreate(midiClient, "MIDI input", readProc, nil, &inputPort);

但我收到此错误:“((UnsafePointer,UnsafeMutablePointer,UnsafeMutablePointer)->无效”无法转换为“
MIDIReadProc”

MIDIReadProc的typedef如下:

typealias MIDIReadProc = CFunctionPointer<((UnsafePointer<MIDIPacketList>, UnsafeMutablePointer<Void>, UnsafeMutablePointer<Void>) -> Void)>

有没有一种方法可以让我的readProc方法的函数指针传递给MIDIDestinationCreate API?


阅读 256

收藏
2020-07-07

共1个答案

一尘不染

在Swift 2.0(作为Xcode 7的一部分)中,处理函数指针的C
API使用带注释的函数类型@convention(c)。您可以将任何Swift函数,方法或闭包作为@convention(c)函数类型进行传递-
但前提是该闭包符合C约定……例如,它无法从其周围的范围捕获状态。

有关详细信息,请参见 The Swift Programming Language Type
Attributes

__


至于Xcode 6中的功能:Swift
1.x无法将Swift函数或闭包转换为C函数指针-该CFunctionPointer类型的唯一用途是将从(Obj)C
API导入的函数指针传递给其他(Obj)C API。

您可以在C代码中声明一个函数指针,然后通过项目的桥接标头将其公开给Swift,然后使用Swift将其传递给CoreMIDI。但是由于无论如何都要跨过桥梁,所以您可能会想到最好将项目的哪些部分保留在C中,以及从这些部分到Swift代码的最佳接口是什么。

2020-07-07