1

有一个C结构:

struct SomeStruct;

还有一个 C 函数使用这个结构作为双指针参数:

C_exampleFunction(struct SomeStruct** someClass)

我想将任何 Swift 类或对象传递给这个函数以使用它的功能。然而 Swift 端的 C 函数只接受 UnsafeMutablePointer 作为参数:

mySwiftFunction(for obj: AnyObject) {
   let objUnsafeMutableRawPointer = Unmanaged.passUnretained(obj).toOpaque()
   let objOpaquePointer = OpaquePointer(objUnsafeMutableRawPointer)
   let someClassArg = UnsafeMutablePointer<OpaquePointer?>(objOpaquePointer)

   C_exampleFunction(someClassArg)
}

即使我解除分配指针,代码也总是会产生一些内存错误。我的主要问题是如何将对象作为 UnsafeMutablePointer 添加到上面这样的 C 函数中?

我检查了这些来源(但没有运气):

我得到的错误是:

Thread 1: EXC_BAD_ACCESS (code=1, address=0x6ba571ac0)

感谢您的回答、反馈,尤其是您提前提供的时间。

4

1 回答 1

1

我认为通过不完整的类型指针传递给 C 函数的 Swift 对象可以做的事情相对较少,但如果你需要这样做,你就走在了正确的轨道上。

我在您问题中的代码中看到的一个问题是该行

let someClassArg = UnsafeMutablePointer<OpaquePointer?>(objOpaquePointer)

这里someClassArg仍然obj是传递给的指针mySwiftFunction(),它只是转换为不同的指针类型。但是,C_exampleFunction()需要一个指向指针的指针obj。因此,代码很可能会崩溃。

您可以通过将有问题的行替换为

let someClassArg = UnsafeMutablePointer<OpaquePointer?>.allocate(capacity: 1)
someClassArg.pointee = objOpaquePointer

还有其他方法。例如,您可以objOpaquePointer使用inout语法传递;不过,它需要一个var才能起作用。你也可以避免Unmanaged这样使用:

let objUnsafeMutablePtr = UnsafeMutablePointer<AnyObject>.allocate(capacity: 1)
objUnsafeMutablePtr.pointee = obj
var objOpaquePtr : OpaquePointer! = OpaquePointer(objUnsafeMutablePtr)
C_exampleFunction(&objOpaquePtr) 

(这里我们将不透明指针作为 传递inout)。

无论采用哪种方法,都应该非常小心obj. 例如,如果您使用Unmanaged,您可能想要使用passRetained()(然后takeRetainedValue()在检索对象时),但这取决于您的用例。

这是另一个关于手动内存管理的有用资源:

https://developer.apple.com/documentation/swift/swift_standard_library/manual_memory_management

于 2019-12-07T19:21:41.713 回答