c - 了解 IOKit 中的 CFSet 和 IOHIDDeviceRegisterRemovalCallback

标签 c macos core-foundation iokit

我正在尝试理解 IOKit 用户空间中的一段代码,该代码是使用 CFSet、CFAllocator 和其他非 NS*/Swift 结构用 C 语言编写的。

https://opensource.apple.com/source/IOKitUser/IOKitUser-1445.40.1/hid.subproj/IOHIDDevice.c.auto.html

https://developer.apple.com/library/archive/technotes/tn2187/_index.html

让我们以 IOHIDDeviceRegisterRemovalCallback()__IOHIDDeviceNotification() 为例(类似的函数也是如此,例如 IOHIDDeviceRegisterInputValueCallback__IOHIDDeviceRegisterInputReportCallback

IOHIDDeviceRegisterRemovalCallback() 似乎以能够同时处理多个回调的方式注册回调。这是因为它将 infoRef 添加到名为 removalCallbackSetCFSet 中。然后__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;"

https://www.reddit.com/r/iOSProgramming/comments/9jkaye/understanding_lowerlevel_cfset_and_an_iokit/e6sigfw/

关于c - 了解 IOKit 中的 CFSet 和 IOHIDDeviceRegisterRemovalCallback,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52548971/

相关文章:

c - 使用有序编译指示的 msvc 上的 openmp 比预期慢

c - 如何正确使用c中的线程和套接字?

cocoa - 64 位首选项 Pane 显示窗口

cocoa - Mac OS 上 Glib 夸克的模拟

c++ - Mac OSX Sierra CoreFoundation/CoreServices/CoreGraphics 不工作

c - 原子位测试和设置 (BTS) 的内在汇编

c - 如何在 C 中为特定的日期、月份和年份创建 UTC 时间?

MacOS - 请求音频/相机许可 - 显示错误的应用程序标题?

c - 从 OSX 上的 dlopen 句柄查找路径名

core-graphics - 如何在 Swift 3 中使用 CFDictionaryCreate?