gpt4 book ai didi

swift - 如何在 Swift 中构造 UnsafeMutablePointer> 类型?

转载 作者:行者123 更新时间:2023-11-28 05:43:11 24 4
gpt4 key购买 nike

我正在使用 Swift 与核心 MIDI API 进行交互,但在使用 MIDIThruConnectionFind 函数时遇到了一些问题。

documentation陈述如下

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

这是我的功能,无论我尝试什么,我都会遇到构建错误。例如,变量被使用但未初始化,类型错误等。

@IBAction func listConnections(_ sender: Any) {
var connectionRef: Unmanaged<CFData>

MIDIThruConnectionFind("" as CFString, &connectionRef)
}

我期望的是我应该为 outConnectionList 提供一个指向指针的地址,并且该函数正在为数据分配内存。但是我如何在 Swift 中做到这一点?

更新

至少这样可以编译,但是如何取消引用和访问数据?

@IBAction func listConnections(_ sender: Any) {
let connectionRefs = UnsafeMutablePointer<Unmanaged<CFData>>.allocate(capacity: 1)

MIDIThruConnectionFind("" as CFString, connectionRefs)
}

最佳答案

我有点猜测,目前无法实际测试代码,但这是我的想法:

MIDIThruConnectionFind()函数在 MIDIThruConnection.h 中声明为

extern OSStatus
MIDIThruConnectionFind( CFStringRef inPersistentOwnerID,
CFDataRef __nonnull * __nonnull outConnectionList )

因此导入到 Swift 作为

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

这意味着最后一个参数必须是(已初始化和)非可选 Unmanaged<CFData> 的地址值(value)。

但这没有意义:数据是由函数分配的,我们不想传递任何数据。我强烈认为这是 C 头文件中该函数的可空性注释中的错误。其他具有输出参数的核心 MIDI 函数已正确注释,例如

extern OSStatus
MIDIObjectGetStringProperty( MIDIObjectRef obj,
CFStringRef propertyID,
CFStringRef __nullable * __nonnull str )

以下解决方法可能有效:声明 connectionRef作为一个可选指针(因此它被初始化为nil),并在调用函数时将其“转换”为一个非可选指针:

var connectionRef: Unmanaged<CFData>?

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

如果成功,可选指针可以解包,CFData使用 takeRetainedValue() 获得的引用. CFData是免费桥接到 NSData , 并且可以转换为 Swift 覆盖类型 Data :

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)

关于swift - 如何在 Swift 中构造 UnsafeMutablePointer<Unmanaged<CFData>> 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55879035/

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