gpt4 book ai didi

macos - IOKit 设备添加/删除通知 - 只触发一次?

转载 作者:行者123 更新时间:2023-12-03 16:11:41 25 4
gpt4 key购买 nike

我一直在尝试在添加或删除特定 USB 设备时收到通知。我已阅读“从应用程序访问硬件”文档,并有一个简单的演示应用程序,主要基于该文档中提供的代码。

第一次添加或删除设备时它会起作用,但此后我的回调永远不会被调用。我不明白为什么?谁能发现我哪里出错了?

(xcode 项目,如果您想测试) http://monkeyfood.com/testIOKitNOtificaiton.zip

谢谢。

//
// AppDelegate.m
// testIOKitNotification
//
// Created by Diggory Laycock on 23/07/2012.
// Copyright (c) 2012 MonkeyFood.com. All rights reserved.
//

#import "AppDelegate.h"

@implementation AppDelegate


// Arduino USB info
#define matchVendorID 0x2341
#define matchProductID 0x0043


#pragma mark -
#pragma mark C Callback functions
#pragma mark -

void usbDeviceAppeared(void *refCon, io_iterator_t iterator){
NSLog(@"Matching USB device appeared");
}
void usbDeviceDisappeared(void *refCon, io_iterator_t iterator){
NSLog(@"Matching USB device disappeared");
}


@synthesize window = _window;


#pragma mark -
#pragma mark Application Methods
#pragma mark -



- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
io_iterator_t newDevicesIterator;
io_iterator_t lostDevicesIterator;

newDevicesIterator = 0;
lostDevicesIterator = 0;
NSLog(@" ");

NSMutableDictionary *matchingDict = (__bridge NSMutableDictionary *)IOServiceMatching(kIOUSBDeviceClassName);

if (matchingDict == nil){
NSLog(@"Could not create matching dictionary");
return;
}
[matchingDict setObject:[NSNumber numberWithShort:matchVendorID] forKey:(NSString *)CFSTR(kUSBVendorID)];
[matchingDict setObject:[NSNumber numberWithShort:matchProductID] forKey:(NSString *)CFSTR(kUSBProductID)];

// Add notification ports to runloop
IONotificationPortRef notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
CFRunLoopSourceRef notificationRunLoopSource = IONotificationPortGetRunLoopSource(notificationPort);
CFRunLoopAddSource([[NSRunLoop currentRunLoop] getCFRunLoop], notificationRunLoopSource, kCFRunLoopDefaultMode);

kern_return_t err;
err = IOServiceAddMatchingNotification(notificationPort,
kIOMatchedNotification,
(__bridge CFDictionaryRef)matchingDict,
usbDeviceAppeared,
(__bridge void *)self,
&newDevicesIterator);
if (err)
{
NSLog(@"error adding publish notification");
}
[self matchingDevicesAdded: newDevicesIterator];


NSMutableDictionary *matchingDictRemoved = (__bridge NSMutableDictionary *)IOServiceMatching(kIOUSBDeviceClassName);

if (matchingDictRemoved == nil){
NSLog(@"Could not create matching dictionary");
return;
}
[matchingDictRemoved setObject:[NSNumber numberWithShort:matchVendorID] forKey:(NSString *)CFSTR(kUSBVendorID)];
[matchingDictRemoved setObject:[NSNumber numberWithShort:matchProductID] forKey:(NSString *)CFSTR(kUSBProductID)];


err = IOServiceAddMatchingNotification(notificationPort,
kIOTerminatedNotification,
(__bridge CFDictionaryRef)matchingDictRemoved,
usbDeviceDisappeared,
(__bridge void *)self,
&lostDevicesIterator);
if (err)
{
NSLog(@"error adding removed notification");
}
[self matchingDevicesRemoved: lostDevicesIterator];


// CFRunLoopRun();
// [[NSRunLoop currentRunLoop] run];

}

#pragma mark -
#pragma mark ObjC Callback functions
#pragma mark -

- (void)matchingDevicesAdded:(io_iterator_t)devices
{
io_object_t thisObject;
while ( (thisObject = IOIteratorNext(devices))) {
NSLog(@"new Matching device added ");
IOObjectRelease(thisObject);
}

}


- (void)matchingDevicesRemoved:(io_iterator_t)devices
{
io_object_t thisObject;
while ( (thisObject = IOIteratorNext(devices))) {
NSLog(@"A matching device was removed ");
IOObjectRelease(thisObject);
}

}


@end

最佳答案

我有点晚了,因为有一个可接受的答案,但要解决这个问题,您需要在回调中迭代匹配的设备迭代器。但这样做并不简单,因此这里是实现这一点的代码,因为回调是一个 C 函数,并且您希望将其桥接到您的 Objective C 方法。

void usbDeviceAppeared(void *refCon, io_iterator_t iterator){
NSLog(@"Matching USB device appeared");
SerialMonitor *monitor = (__bridge SerialMonitor *)refCon;
[monitor matchingDevicesAdded:iterator];
[monitor reload];
}

void usbDeviceDisappeared(void *refCon, io_iterator_t iterator){
NSLog(@"Matching USB device disappeared");
SerialMonitor *monitor = (__bridge SerialMonitor *)refCon;
[monitor matchingDevicesRemoved:iterator];
[monitor reload];
}

SerialMonitor 是我的 USB 设备管理器类,reload 是一种执行适当 USB 设备初始化(获取功能报告和交换数据)的方法。

关于macos - IOKit 设备添加/删除通知 - 只触发一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11628195/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com