c - 将 C 回调(无上下文)包装到 Swift 闭包中
问题描述
我正在尝试通过使用 GLFW 的包装器来学习 Swift
GLFW 允许添加错误回调:
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);
在哪里
typedef void (* GLFWerrorfun)(int,const char*);
我尝试了谷歌搜索,但许多解决方案都提到回调期望代表上下文的最终参数。
不幸的是我在这里没有上下文参数。
这似乎应该起作用(尽管 OP 明确要求类似于我的情况,没有上下文参数):
class glfw {
typealias ErrorFun = (Int, _ description: String) -> Void
func setErrorCallback(cbFun: ErrorFun) {
// Void pointer to `self`:
let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())
glfwSetErrorCallback { err, desc in
// Extract pointer to `self` from void pointer:
let mySelf = Unmanaged<glfw>.fromOpaque(observer).takeUnretainedValue()
...
}
}
}
但它一直在发射:
错误:不能从捕获上下文的闭包中形成 C 函数指针
一旦我尝试observer
在回调中使用,上下文似乎被捕获
我该如何解决?
解决方案
通过使用全局变量解决
public struct glfw {
static func setErrorCallback(cbFun: @escaping ErrorFun) {
_g.errorCB = cbFun
glfwSetErrorCallback { err, desc in
_g.errorCB!(Error(rawValue: err)!, String(utf8String: desc!)!)
}
}
var errorCB: ErrorFun?
}
var _g = glfw()
推荐阅读
- python - 如何更改 python 文件单元格 VS Code 的背景?
- ios - 本机 iOS Unity 集成 - AppStore 配置文件导致找不到“UnityFramework/UnityFramework.h”文件
- r - 从 SF 数据框中排除外岛
- debezium - Debezium Server 并在 application.properties 文件中使用变量
- javascript - wavesurfer.js 的 Regions 插件根本不工作
- python-3.x - Kafka 消费者断开连接 - 断开连接(在状态 UP 684744 毫秒后)
- c++ - 在编译时从文本文件初始化字符串向量
- azure-data-factory - 遍历 azure 数据工厂中的文件夹
- python - Selenium 使用 OR/AND 运算符选择特定内容 - python
- ios - 使用 Swift 进行子视图垂直对齐