Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.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
如何构造unsafemeutablepointer<;非托管<;CFData>&燃气轮机;输入Swift?_Swift_Coremidi - Fatal编程技术网

如何构造unsafemeutablepointer<;非托管<;CFData>&燃气轮机;输入Swift?

如何构造unsafemeutablepointer<;非托管<;CFData>&燃气轮机;输入Swift?,swift,coremidi,Swift,Coremidi,我正在使用Swift与核心MIDI API交互,并且在使用midithronnectionfind函数时遇到了一些问题 缔约国声明如下: func MIDIThruConnectionFind(_ inPersistentOwnerID: CFString, _ outConnectionList: UnsafeMutablePointer<Unmanaged<CFData>>) -> OSStatus 我有点猜测,目

我正在使用Swift与核心MIDI API交互,并且在使用
midithronnectionfind
函数时遇到了一些问题

缔约国声明如下:

func MIDIThruConnectionFind(_ inPersistentOwnerID: CFString, 
                      _ outConnectionList: UnsafeMutablePointer<Unmanaged<CFData>>) -> OSStatus

我有点猜测,目前还不能实际测试代码,但我的想法如下:

midithronnectionfind()
函数在midithronnection.h中声明为

extern OSStatus
MIDIThruConnectionFind(     CFStringRef                     inPersistentOwnerID,
                            CFDataRef __nonnull * __nonnull outConnectionList )
因此,作为

public func MIDIThruConnectionFind(_ inPersistentOwnerID: CFString,
            _ outConnectionList: UnsafeMutablePointer<Unmanaged<CFData>>) -> OSStatus
以下解决方法可能有效:将
connectionRef
声明为可选指针(以便将其初始化为
nil
),并在调用函数时将其“强制转换”为非可选指针:

var connectionRef: Unmanaged<CFData>?

let status = withUnsafeMutablePointer(to: &connectionRef) {
    $0.withMemoryRebound(to: Unmanaged<CFData>.self, capacity: 1) {
        MIDIThruConnectionFind("" as CFString, $0)
    }
}

另一种解决方法是在桥接头文件中定义具有正确的可空性注释的包装函数:

#include <CoreMIDI/CoreMIDI.h>

static OSStatus myMIDIThruConnectionFind(CFStringRef inPersistentOwnerID,
                                          CFDataRef __nullable * __nonnull outConnectionList) {
    return MIDIThruConnectionFind(inPersistentOwnerID, outConnectionList);
}
#包括
静态OSStatus MymidthrothronnectionFind(持久所有者ID中的CFStringRef,
CFDataRef _可空*_非空外部连接列表){
返回midithronnectionfind(inPersistentOwnerID,outConnectionList);
}
可以称之为

var connectionRef: Unmanaged<CFData>?
let status = myMIDIThruConnectionFind("" as CFString, &connectionRef)
var connectionRef:非托管?
让status=mymidithronnectionfind(“”作为CFString,&connectionRef)
  • 要快速回答,您确实喜欢这样
//创建非托管
var unmanagedData=Unmanaged.passUnretained(数据()作为CFData)
知道是使用保留还是未保留取决于上下文。对于coreMidi对象,我假设coreMidi执行内存管理

  • 关于“如何访问数据”,你需要恢复内存
下面是两个与CoreMidi交互的函数的示例。一个用于单个值,另一个用于值数组(如您的问题所示)

请注意,在现实生活中,最好将函数声明为抛出,并在CoreMidi函数返回错误时抛出一些快速错误。 在本例中,如果失败,我们只返回nil

单值案例

func getmidithronnectionparams(connectionRef:midithronnectionref)->midithronnectionparams?{
//1-分配非托管CFData
var unmanagedData=Unmanaged.passUnretained(数据()作为CFData)
//2-将数据指针传递给C API
设err=midithronnectiongetparams(connectionRef和unmanagedData)
保护错误==noErr else{
归零
}
//3-从非托管CFData中提取数据
让data=unmanagedData.takeUnrepainedValue()作为数据
//4-重新映射到swift类型
返回data.withUnsafeBytes{bytes->MidithrConnectionParams中的
UnsafeRawPointer(字节)。AssumingMemoryBind(到:midithrConnectionParams.self)。指针对象
}
}
数组大小写

func getmidithronnections()->[midithronnectionref]?{
//1-分配非托管数据引用
var unmanagedData=Unmanaged.passUnretained(数据()作为CFData)
//2-将数据指针传递给C API
让err=midithronnectionfind(“com.moosefactory.midiCenter.midiThru”作为CFString,&unmanagedData)
保护错误==noErr else{
归零
}
//3-从非托管数据中提取CFData
//我们更喜欢CFData而不是这里的数据,以访问指针和大小
让cfData=unmanagedData.takeUnrepainedValue()
保护let dataPtr=CFDataGetBytePtr(cfData)else{
归零
}
//4-计算元素的数量
让dataSize=CFDataGetLength(cfData)
让numberOfConnections=dataSize/MemoryLayout.stride
//5-从到的反弹指针
返回带有MemoryRebound的数据ptr.(到:midithronnectionref.self,
容量:numberOfConnections){typedPtr in
//将指针转换为缓冲区指针
let bufferPointer=UnsafeBufferPointer(开始:typedPtr,计数:numberOfConnections)
//构造数组
return[midithronnectionref].init(unsafeUninitializedCapacity:numberOfConnections){refPtr,计入
计数=连接数

对于0中的i..related@ihatetoregister:您有机会检查答案吗?请提供一些反馈:)代码可以编译(并且不会崩溃),但遗憾的是,我目前无法测试它是否真的有效。如果无效,请告诉我,然后我将删除答案。
var connectionRef: Unmanaged<CFData>?

let status = withUnsafeMutablePointer(to: &connectionRef) {
    $0.withMemoryRebound(to: Unmanaged<CFData>.self, capacity: 1) {
        MIDIThruConnectionFind("" as CFString, $0)
    }
}
if status == noErr, let connectionRef = connectionRef {
    let data = connectionRef.takeRetainedValue() as Data

}
#include <CoreMIDI/CoreMIDI.h>

static OSStatus myMIDIThruConnectionFind(CFStringRef inPersistentOwnerID,
                                          CFDataRef __nullable * __nonnull outConnectionList) {
    return MIDIThruConnectionFind(inPersistentOwnerID, outConnectionList);
}
var connectionRef: Unmanaged<CFData>?
let status = myMIDIThruConnectionFind("" as CFString, &connectionRef)