Swift传递MTLTexture指针给C++后回转触发EXC_BAD_ACCESS如何解决?
问题根源
你在Swift侧使用&texture传递参数的写法是错误的,传入C++的并不是MTLTexture对象本身的指针:
- Swift中用
&传递的是inout参数,对应指针类型是UnsafeMutablePointer<MTLTexture>,也就是指向MTLTexture引用的二级指针,本质是Swift侧存储texture变量的栈内存地址,不是MTLTextureOC对象本身的地址。 - C++侧拿到的
textureHandle实际是栈地址,你把栈地址当成OC对象指针用__bridge转id<MTLTexture>,访问对象成员时自然会触发野指针崩溃,哪怕地址不为0也不是合法的OC对象地址。
解决方法
因为你不能修改C++侧逻辑,只需要在Swift侧把MTLTexture对象转成裸的void*指针直接传递即可,不需要加&:
func foo(texture: MTLTexture) { // 将对象转换为C++侧需要的void*裸指针 let textureHandle = Unmanaged.passUnretained(texture).toOpaque() // 直接传指针,不要加& EndModifyTexture(textureHandle) }
注意事项
- 上述代码使用
passUnretained不会增加对象的引用计数,仅适用于C++侧同步调用EndModifyTexture、不会异步持有指针的场景,你需要保证调用全程texture对象不会被Swift的ARC释放。 - 如果C侧会异步持有这个
MTLTexture指针,你需要改用Unmanaged.passRetained(texture).toOpaque()传递,且需要在C侧用完指针后调用CFRelease释放所有权,避免内存泄漏。
补充验证
你可以在Swift侧分别打印以下两个值对比差异:
// 打印变量的栈地址,也就是你之前用&传入C++的值 print(withUnsafeMutablePointer(to: &texture) { $0 }) // 打印MTLTexture对象本身的地址,也就是C++侧需要的正确值 print(Unmanaged.passUnretained(texture).toOpaque())
二者完全不一致,也能直接验证你之前传参错误的问题。
内容的提问来源于stack exchange,提问作者Sirop4ik
相关产品推荐
相关产品推荐

