我正在尝试理解 IOKit 用户空间中的一段代码,该代码是使用 CFSet、CFAllocator 和其他非 NS*/Swift 结构用 C 语言编写的。
https://developer.apple.com/library/archive/technotes/tn2187/_index.html
让我们以 IOHIDDeviceRegisterRemovalCallback()
和 __IOHIDDeviceNotification()
为例(类似的函数也是如此,例如 IOHIDDeviceRegisterInputValueCallback
和 __IOHIDDeviceRegisterInputReportCallback
。
IOHIDDeviceRegisterRemovalCallback() 似乎以能够同时处理多个回调的方式注册回调。这是因为它将 infoRef
添加到名为 removalCallbackSet
的 CFSet
中。然后__IOHIDDeviceNotification,它似乎是为此用户空间代码下方的层注册的单个回调,它被调用一次,然后循环通过removeCallbackSet并触发多个注册的回调中的每一个。
但是,在我的第二个链接中,文档提到为了“取消注册”回调,您需要将 null/nil 传递给注册函数。这没有任何意义。 infoRef
现在是 {callback=nil, context=nil} 的实例,并从 CFSet 中删除该值。但该值一开始就不会出现在集合中,因为集合项的形式为 {callback=, context=}。
1) 我是否遗漏了什么,或者 CFSetRemoveValue 调用实际上无用,并且您实际上无法从 IOHIDDeviceRef 中删除回调?
2)我认为 CFSet 正在比较回调和上下文变量上的 infoRef 值,而不是指向 infoRef 本身的指针,我的想法是否正确?
3)我是否遗漏了 CFAllocator 工作原理的某些内容?
4) CFSet 是否仅使用 context
的值,因此您可以通过传递相同的上下文但传递 nil 回调来取消注册?
最佳答案
“数字 4 是正确的。
__IOHIDDeviceCallbackBaseDataIsEqual 是集合中的项目相互比较的方式。它只检查上下文。
结果 = info1->context == info2->context;"
关于c - 了解 IOKit 中的 CFSet 和 IOHIDDeviceRegisterRemovalCallback,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52548971/