mac osx 中 runModalWindow 阻塞usb数据接收线程
来源:互联网 发布:襄县农村淘宝招聘 编辑:程序博客网 时间:2024/06/17 01:26
在mac osx 下使用IOHidInterface 与 USB Hid进行通信
USBHid.h
#ifndef USBHid_h#define USBHid_h#import <Foundation/Foundation.h>#include <IOKit/hid/IOHIDLib.h>#include <IOKit/hid/IOHIDKeys.h>@protocol UsbHIDDelegate <NSObject>@optional- (void)usbhidDidRecvData:(uint8_t*)recvData length:(CFIndex)reportLength;- (void)usbhidDidMatch;- (void)usbhidDidRemove;@end@interface UsbHID : NSObject { IOHIDManagerRef managerRef; IOHIDDeviceRef deviceRef;}@property(nonatomic,strong)id<UsbHIDDelegate> delegate;@property(nonatomic) BOOL connected;+ (UsbHID *)sharedManager;- (BOOL)connectHID;- (BOOL)disconnectHID;- (BOOL)senddata:(Byte *)outbuffer size:(int)size;- (int)readdata:(Byte *)readbuffer size:(int)size;- (IOHIDManagerRef)getManageRef;- (void)setManageRef:(IOHIDManagerRef)ref;- (IOHIDDeviceRef)getDeviceRef;- (void)setDeviceRef:(IOHIDDeviceRef)ref;@end#endif /* USBHid_h */
#import <Foundation/Foundation.h>#import <AppKit/AppKit.h>#import "UsbHID.h"@implementation UsbHIDstatic UsbHID *_sharedManager = nil;@synthesize delegate;@synthesize connected;static void MyInputCallback(void* context, IOReturn result, void* sender, IOHIDReportType type, uint32_t reportID, uint8_t *report,CFIndex reportLength) { id<UsbHIDDelegate> dele = [[UsbHID sharedManager] delegate]; [dele usbhidDidRecvData:report length:reportLength];}static void Handle_DeviceMatchingCallback(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) { [[UsbHID sharedManager] setDeviceRef:inIOHIDDeviceRef]; char *inputbuffer = malloc(64); IOHIDDeviceRegisterInputReportCallback([[UsbHID sharedManager]getDeviceRef], (uint8_t*)inputbuffer, 64, MyInputCallback, NULL); [UsbHID sharedManager].connected = true; NSLog(@"%p设备插入,现在usb设备数量:%ld",(void *)inIOHIDDeviceRef,USBDeviceCount(inSender)); [[[UsbHID sharedManager] delegate] usbhidDidMatch];}static void Handle_DeviceRemovalCallback(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) { [[UsbHID sharedManager] setDeviceRef:nil]; [UsbHID sharedManager].connected = false; NSLog(@"%p设备拔出,现在usb设备数量:%ld",(void *)inIOHIDDeviceRef,USBDeviceCount(inSender)); [[[UsbHID sharedManager] delegate] usbhidDidRemove];}static long USBDeviceCount(IOHIDManagerRef HIDManager){ CFSetRef devSet = IOHIDManagerCopyDevices(HIDManager); if(devSet) return CFSetGetCount(devSet); return 0;}+(UsbHID *)sharedManager { @synchronized( [UsbHID class] ){ if(!_sharedManager) _sharedManager = [[self alloc] init]; return _sharedManager; } return nil;}+(id)alloc { @synchronized ([UsbHID class]){ NSAssert(_sharedManager == nil, @"Attempted to allocated a second instance"); _sharedManager = [super alloc]; return _sharedManager; } return nil;}- (id)init { self = [super init]; if (self) { managerRef = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); IOHIDManagerScheduleWithRunLoop(managerRef, CFRunLoopGetMain(), kCFRunLoopDefaultMode); IOReturn ret = IOHIDManagerOpen(managerRef, 0L); if (ret != kIOReturnSuccess) { NSAlert *alert = [NSAlert alertWithMessageText:@"error" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"打开设备失败!"]; [alert runModal]; return self; } const long vendorID = 0x0483; const long productID = 0x5750; NSMutableDictionary* dict= [NSMutableDictionary dictionary]; [dict setValue:[NSNumber numberWithLong:productID] forKey:[NSString stringWithCString:kIOHIDProductIDKey encoding:NSUTF8StringEncoding]]; [dict setValue:[NSNumber numberWithLong:vendorID] forKey:[NSString stringWithCString:kIOHIDVendorIDKey encoding:NSUTF8StringEncoding]]; IOHIDManagerSetDeviceMatching(managerRef, (__bridge CFMutableDictionaryRef)dict); IOHIDManagerRegisterDeviceMatchingCallback(managerRef, &Handle_DeviceMatchingCallback, NULL); IOHIDManagerRegisterDeviceRemovalCallback(managerRef, &Handle_DeviceRemovalCallback, NULL); NSSet* allDevices = (__bridge NSSet*)(IOHIDManagerCopyDevices(managerRef)); NSArray* deviceRefs = [allDevices allObjects]; if (deviceRefs.count==0) { } } return self;}- (void)dealloc { IOReturn ret = IOHIDDeviceClose(deviceRef, 0L); if (ret == kIOReturnSuccess) { deviceRef = nil; } ret = IOHIDManagerClose(managerRef, 0L); if (ret == kIOReturnSuccess) { managerRef = nil; }}- (BOOL)connectHID { NSSet* allDevices = (__bridge NSSet*)(IOHIDManagerCopyDevices(managerRef)); NSArray* deviceRefs = [allDevices allObjects]; deviceRef = (deviceRefs.count)?(__bridge IOHIDDeviceRef)[deviceRefs objectAtIndex:0]:nil; if (deviceRef){ IOReturn ret = IOHIDDeviceOpen(deviceRef, 0L); if (ret != kIOReturnSuccess) return false; self.connected = true; return true; } return false;}-(BOOL)disconnectHID{ if (deviceRef){ IOReturn ret = IOHIDDeviceClose(deviceRef, 0L); if (ret != kIOReturnSuccess) return false; self.connected = false; return true; } return false; }- (BOOL)senddata:(Byte*)outbuffer size:(int)size { if (!deviceRef) { return false; } IOReturn ret = IOHIDDeviceSetReport(deviceRef, kIOHIDReportTypeOutput, 0, (uint8_t*)outbuffer, size); if (ret != kIOReturnSuccess) { NSAlert* alert = [NSAlert alertWithMessageText:@"error" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"发送数据失败!"]; [alert runModal]; return false; } return true;}- (int)readdata:(Byte*)readbuffer size:(int)size { if (!deviceRef) { return 0; } CFIndex sizecf = (CFIndex)size; IOReturn ret = IOHIDDeviceGetReport(deviceRef, kIOHIDReportTypeFeature, 0, (uint8_t *)readbuffer, (CFIndex *) &sizecf ); if (ret != kIOReturnSuccess) { NSAlert* alert = [NSAlert alertWithMessageText:@"error" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"接收数据失败!"]; [alert runModal]; return 0; } return (int)sizecf;}- (IOHIDManagerRef)getManageRef { return managerRef;}- (void)setManageRef:(IOHIDManagerRef)ref { managerRef = ref;}- (IOHIDDeviceRef)getDeviceRef { return deviceRef;}- (void)setDeviceRef:(IOHIDDeviceRef)ref { deviceRef = ref;}@end
可以看到usb hid 的接收数据是使用回调的方式触发的。
之后发现在使用runModalWindow弹出模态窗口NSWindow之后,会突然无法接收到usb hid 的数据,在回调处打上断点之后一直没有进来,猜想可能是这个回调线程是基于当前的NSWindow,在runModal另一个NSWindow之后,将原来的NSWindow的线程阻塞了,
解决方法就是不要使用runModal方法,使用beginSheet方法。
例如对于NSOpenlPanel,使用
let panel : NSOpenPanel = NSOpenPanel() let fileTypes : NSArray = ["PNG"] panel.message = "Select a PNG file" panel.prompt = "OK" panel.canChooseFiles = true panel.allowsMultipleSelection = false panel.allowedFileTypes = (fileTypes as! [String]) // let result : Int = panel.runModal() panel.beginWithCompletionHandler { (result) -> Void in if (result == NSFileHandlingPanelOKButton){ } else{ } }
使用beginsheet方法后,就可以不影响usb hid的接收数据了
阅读全文
0 0
- mac osx 中 runModalWindow 阻塞usb数据接收线程
- 將USB隨身碟變MAC OSX安裝碟
- c# USB数据接收
- Mac OSX中设置路由
- Mac osx中使用gitk
- LWIP接收数据阻塞问题
- 安卓usb数据接收
- MAC OSX 下的USB设备连接与访问
- MAC 上 OSX 安装成usb启动盘的命令
- 新建接收数据线程
- 在mac OSX中安装启动zookeeper
- Mac OSX中memcached安装测试
- Mac OSX 中JDK设置问题
- 在Mac OSX中配置CTags插件
- Mac OSX中memcached安装测试
- mac osx
- Socket异步阻塞进行接收数据
- 求助:关于MAC下的用UVC协议通过USB接口从外接设备接收数据问题
- nginx基本配置与参数说明
- ScrollView 嵌套 Recyclerview 滑动冲突
- centos6.5上静默安装oracle11g
- HIbernate的概述
- C++中类成员函数作为回调函数
- mac osx 中 runModalWindow 阻塞usb数据接收线程
- csdn搜索自己的文章
- 234. Palindrome Linked List
- java读取src下面properties文件
- Linux出现问题1
- Access violation at address 77106D4E in module 'ntdll.dll'. Write of address 004051A5.
- Android 禁止 ListView 上下滑动
- csu1224 ACM小组的古怪象棋
- css控制单行文本溢出