Usb 从IOKit(CoreFoundation)接收已插入设备的通知时出现问题

Usb 从IOKit(CoreFoundation)接收已插入设备的通知时出现问题,usb,xcode4,core-foundation,iokit,Usb,Xcode4,Core Foundation,Iokit,我目前正在10.6.7上开发一个应用程序,当插入一个新的usb设备时,它应该会收到通知。我发现有一个IOKit函数可以处理这样的东西“IOServiceAddMatchingNotification”。因为这个特定函数的返回值是0,所以我认为问题可能出在我的匹配字典中,它被赋予了这个函数。我这样声明字典: CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName); 因为我不想收到每个设备的通知,

我目前正在10.6.7上开发一个应用程序,当插入一个新的usb设备时,它应该会收到通知。我发现有一个IOKit函数可以处理这样的东西“IOServiceAddMatchingNotification”。因为这个特定函数的返回值是0,所以我认为问题可能出在我的匹配字典中,它被赋予了这个函数。我这样声明字典:

CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
因为我不想收到每个设备的通知,所以我不知道这是否是创建此特定词典的正确方法

我的完整代码如下所示:

ioKitNotificationPort = IONotificationPortCreate(kIOMasterPortDefault);
notificationRunLoopSource = IONotificationPortGetRunLoopSource(ioKitNotificationPort);

CFRunLoopAddSource(CFRunLoopGetCurrent(), notificationRunLoopSource, kCFRunLoopDefaultMode);

CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);


addMatchingNotificationResult = IOServiceAddMatchingNotification(ioKitNotificationPort,
                                                                 kIOPublishNotification,
                                                                 matchingDict,
                                                                 deviceAdded,
                                                                 NULL,
有人知道为什么这行不通吗? (注意:回调函数是一个静态void c函数,其余的是封装在 ide(一个Obj-C类)

谢谢


Xcode 4,10.6.7

我认为您所描述的最简单的方法是连接到DiskArbitration框架。DA对于OSX来说是相对较新的,它允许userland应用程序在设备连接时检查设备。它是用来在连接iPod时打开iTunes,在连接摄像头时启动iPhoto等。。。如果您正在寻找的USB设备是存储设备,那么这将适用于您。否则,您将需要使用匹配的字典路径…

在我看来,您应该在opensource.apple.com上下载源代码表单IOUSBFamily,然后找到USB Prober的代码,此应用程序执行与您描述的完全相同的操作,监听USB设备附件。(此外,USB Prober还可以获得通用设备和配置描述符,也许这也是您需要的东西。)

奇怪的是,在启用通知之前,您必须清空IOServiceAddMatchingNotification返回的迭代器。我在提供的代码中没有看到这一点,因此这可能是问题所在。实际上,要保持通知运行,您需要保留迭代器

io_iterator_t ioNotification;

addMatchingNotificationResult = IOServiceAddMatchingNotification(ioKitNotificationPort,
                                                                 kIOPublishNotification,
                                                                 matchingDict,
                                                                 deviceAdded,
                                                                 NULL,
                                                                 &ioNotification);

while ((service = IOIteratorNext(ioNotification)))
{
    NSLog(@"Hey, I found a service!");

    IOObjectRelease(service); // yes, you have to release this
}

您是否将要查找的设备的VID和PID添加到匹配的字典中?对于您拥有的字典,并且VID=yourVid,PID=yourPid,它将是:

CFDictionaryAddValue(matchingDict, usbVendorId, yourVid);  
CFDictionaryAddValue(matchingDict, usbProductId, yourPid);  

另一件事-在调用IOServiceAddMatchingNotification成功后,您需要使用调用中设置的迭代器调用设备添加的处理程序。这将启动通知并检查现有设备。

我对IOKit的用户空间方面还不是很熟悉,但在内核方面,匹配首先发生在最具体的匹配字典,只有在失败的情况下,才会尝试更一般的匹配。您是否在现有驱动程序已经匹配的设备上尝试此功能?此外,也许这会有所帮助:我使用了一个usb记忆棒尝试此功能,我现在正在使用它。Finder会找到该记忆棒,因此我认为我不需要在driv中写入条目另外,我喜欢收到以前从未连接到我的mac上的棍棒的通知,所以应该有一种方法来处理这个问题…我仍然找不到那种方法。。。