Swift调用原生库方法时如何创建并传入FuncPtr类型的回调参数
实现方案
无上下文捕获的基础用法
C语言定义的FuncPtr函数指针会被Swift自动桥接为对应签名的C约定闭包,你只需要传入参数、返回值完全匹配的Swift函数或者无捕获闭包即可:
// 定义签名匹配的回调函数 func debugCallback(str1: UnsafePointer<CChar>?, str2: UnsafePointer<CChar>?) { // 把C的const char*转为Swift String guard let s1 = str1.map(String.init(cString:)), let s2 = str2.map(String.init(cString:)) else { return } // 自定义处理逻辑 print("调试日志:\(s1) | \(s2)") } func foo() { // 直接传入函数作为参数 register_debug_callback(debugCallback) }
你也可以直接传入内联闭包简化写法:
func foo() { register_debug_callback { str1, str2 in guard let s1 = str1.map(String.init(cString:)), let s2 = str2.map(String.init(cString:)) else { return } print("调试日志:\(s1) | \(s2)") } }
注意事项
- C函数指针不支持捕获上下文:如果你需要在回调中访问
self、类属性等上下文内容,不能直接在闭包内捕获,需要通过Unmanaged将上下文对象转为指针存储,回调中再读取使用,同时需要自行管理引用计数,避免内存泄露或野指针问题。 - 调用约定适配:Swift 5+ 会自动识别C头文件中的
STDCALL调用约定,无需额外配置;如果出现调用异常崩溃,可以手动给闭包指定调用约定:
let callback: @convention(c, stdcall) (UnsafePointer<CChar>?, UnsafePointer<CChar>?) -> Void = { str1, str2 in // 回调处理逻辑 } register_debug_callback(callback)
内容的提问来源于stack exchange,提问作者Sirop4ik
相关产品推荐
相关产品推荐

