有一个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)
感谢您的回答,反馈,尤其是提前的时间。
答案 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