如何将Swift对象用作UnsafeMutablePointer <OpaquePointer?>到C函数

时间:2019-12-03 16:07:44

标签: c swift pointers unsafemutablepointer

有一个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)

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

1 个答案:

答案 0 :(得分:0)

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

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

let someClassArg = UnsafeMutablePointer<OpaquePointer?>(objOpaquePointer)

这里someClassArg仍然是指向obj的{​​{1}}的指针,只是将其转换为其他指针类型。但是,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()),但这取决于您的用例。

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

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