Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c HIDManager Wierd CFRunLoop终止_Objective C_Macos_Device Driver_Hid - Fatal编程技术网

Objective c HIDManager Wierd CFRunLoop终止

Objective c HIDManager Wierd CFRunLoop终止,objective-c,macos,device-driver,hid,Objective C,Macos,Device Driver,Hid,我已经创建了设备匹配和设备删除回调,并且需要运行CFRunLoop,以便在设备插入和删除时调用这些回调 但问题是,DeviceMatch回调需要花费大量的处理时间,并且取决于要连接的设备,因此我想通过在有限的时间内运行CFRunLoop来检测设备是否被删除,并随之发生设备删除回调 但是,它工作了2次,然后抛出exe\u bad\u访问 设备添加回调 static void Handle_DeviceMatchingCallback(void* inContext, IOReturn inRes

我已经创建了设备匹配和设备删除回调,并且需要运行CFRunLoop,以便在设备插入和删除时调用这些回调

但问题是,DeviceMatch回调需要花费大量的处理时间,并且取决于要连接的设备,因此我想通过在有限的时间内运行CFRunLoop来检测设备是否被删除,并随之发生设备删除回调

但是,它工作了2次,然后抛出exe\u bad\u访问


设备添加回调

static void Handle_DeviceMatchingCallback(void* inContext, IOReturn inResult, 
                             void* inSender, IOHIDDeviceRef  inIOHIDDeviceRef) {
      //DO SOME HEAVY PROCESSING

      //NOW WE NEED TO CHECK IF DEVICE IS STILL CONNECTED
     [[NSRunLoop currentRunLoop]  runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];

      //DO POST PROCESSING

}
设备删除回调:

static void Handle_RemovalCallback( void* inContext,IOReturn  inResult,
                        void*  inSender, IOHIDDeviceRef inIOHIDDeviceRef) {
     //NOW THIS GET's INVOKED, after keeping in run loop

}

以下是生成matchingCFDictRef的代码

CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    CFNumberRef vendorIDCFNumRef  = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &vendorId );
    CFNumberRef productIDCFNumRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &productId );

    CFDictionarySetValue( matchDict, CFSTR( kIOHIDVendorIDKey  ), vendorIDCFNumRef );
    CFDictionarySetValue( matchDict, CFSTR( kIOHIDProductIDKey ), productIDCFNumRef );

    CFRelease( vendorIDCFNumRef );
    CFRelease( productIDCFNumRef );
CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    CFNumberRef vendorIDCFNumRef  = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &vendorId );
    CFNumberRef productIDCFNumRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &productId );

    CFDictionarySetValue( matchDict, CFSTR( kIOHIDVendorIDKey  ), vendorIDCFNumRef );
    CFDictionarySetValue( matchDict, CFSTR( kIOHIDProductIDKey ), productIDCFNumRef );

    CFRelease( vendorIDCFNumRef );
    CFRelease( productIDCFNumRef );

如何生成
匹配cfdictref
?尽管常规惯例会建议IOHIDManager保留或复制它,但也有可能不是。我现在会尝试取出
CFRelease
,看看这是否会改善情况

CFGetTypeID
中的崩溃表示它正试图处理已释放的CF对象。您可以做一些事情来调试它是哪一个:

  • 打开。它可能会工作,即使这是一个CF对象(许多CF对象是免费桥接的,并且仍然可以工作)
  • 在调试器中,将参数选中为
    CFGetType
    。有关取决于处理器的正确寄存器,请参阅。(此页面是否用于ObjC并不重要;您只需要与
    arg0
    相关的entires)

如何生成
匹配cfdictref
?尽管常规惯例会建议IOHIDManager保留或复制它,但也有可能不是。我现在会尝试取出
CFRelease
,看看这是否会改善情况

CFGetTypeID
中的崩溃表示它正试图处理已释放的CF对象。您可以做一些事情来调试它是哪一个:

  • 打开。它可能会工作,即使这是一个CF对象(许多CF对象是免费桥接的,并且仍然可以工作)
  • 在调试器中,将参数选中为
    CFGetType
    。有关取决于处理器的正确寄存器,请参阅。(此页面是否用于ObjC并不重要;您只需要与
    arg0
    相关的entires)

以下是生成匹配CfdictRef的代码

CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    CFNumberRef vendorIDCFNumRef  = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &vendorId );
    CFNumberRef productIDCFNumRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &productId );

    CFDictionarySetValue( matchDict, CFSTR( kIOHIDVendorIDKey  ), vendorIDCFNumRef );
    CFDictionarySetValue( matchDict, CFSTR( kIOHIDProductIDKey ), productIDCFNumRef );

    CFRelease( vendorIDCFNumRef );
    CFRelease( productIDCFNumRef );
CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    CFNumberRef vendorIDCFNumRef  = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &vendorId );
    CFNumberRef productIDCFNumRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &productId );

    CFDictionarySetValue( matchDict, CFSTR( kIOHIDVendorIDKey  ), vendorIDCFNumRef );
    CFDictionarySetValue( matchDict, CFSTR( kIOHIDProductIDKey ), productIDCFNumRef );

    CFRelease( vendorIDCFNumRef );
    CFRelease( productIDCFNumRef );
现在,我看到了不同的堆栈跟踪,从CFRunLoop调用,尽管我仍然在符号中看到GetTypeID

0x00007fff8534407a  <+0023>  jne    0x7fff8534409f <IOHIDDeviceScheduleWithRunLoop+60>
0x00007fff8534407c  <+0025>  mov    0x18(%rdi),%rdi
0x00007fff85344080  <+0029>  mov    (%rdi),%rax
0x00007fff85344083  <+0032>  lea    0x58(%r12),%rsi
0x00007fff85344088  <+0037>  callq  *0x40(%rax)
0x00007fff8534408b  <+0040>  test   %eax,%eax
0x00007fff8534408d  <+0042>  jne    0x7fff85344148 <IOHIDDeviceScheduleWithRunLoop+229>
0x00007fff85344093  <+0048>  cmpq   $0x0,0x58(%r12)
0x00007fff85344099  <+0054>  je     0x7fff85344148 <IOHIDDeviceScheduleWithRunLoop+229>
0x00007fff8534409f  <+0060>  mov    0x58(%r12),%rdi
0x00007fff853440a4  <+0065>  callq  0x7fff85368f36 <dyld_stub_CFGetTypeID>
0x00007fff853440a9  <+0070>  mov    %rax,%rbx
0x00007fff853440ac  <+0073>  callq  0x7fff85369008 <dyld_stub_CFRunLoopSourceGetTypeID>
0x00007fff853440b1  <+0078>  cmp    %rax,%rbx
0x00007fff853440b4  <+0081>  jne    0x7fff853440cc <IOHIDDeviceScheduleWithRunLoop+105>
0x00007fff8534407a jne 0x7fff8534409f
0x00007fff8534407c mov 0x18(%rdi),%rdi
0x00007fff85344080 mov(%rdi),%rax
0x00007fff85344083 lea 0x58(%r12),%rsi
0x00007fff85344088 callq*0x40(%rax)
0x00007fff8534408b测试%eax,%eax
0x00007fff8534408d jne 0x7fff85344148
0x00007fff85344093 cmpq$0x0,0x58(%r12)
0x00007fff85344099 je 0x7fff85344148
0x00007fff8534409f mov 0x58(%r12),%rdi
0x00007fff853440a4呼叫0x7fff85368f36
0x00007fff853440a9移动百分比rax,%rbx
0x00007fff853440ac呼叫0x7fff85369008
0x00007fff853440b1 cmp%rax,%rbx
0x00007fff853440b4 jne 0x7fff853440cc
我看到它在0x00007fff85344080 mov(%rdi),%rax处断开,用于IOHIDDeviceScheduleWithRunLoop(请使用0x00007fff85344080搜索)

在参考文档的帮助下,我看到它是第一个参数,表示tIOHIDManagerRef,我创建了IOHIDManagerRef tIOHIDManagerRef=IOHIDManagerCreate(kcfalocatordefault,kIOHIDOptionsTypeNone)


但是,如何从堆栈跟踪上方查看它的地址?

下面是生成matchingCFDictRef的代码

CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    CFNumberRef vendorIDCFNumRef  = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &vendorId );
    CFNumberRef productIDCFNumRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &productId );

    CFDictionarySetValue( matchDict, CFSTR( kIOHIDVendorIDKey  ), vendorIDCFNumRef );
    CFDictionarySetValue( matchDict, CFSTR( kIOHIDProductIDKey ), productIDCFNumRef );

    CFRelease( vendorIDCFNumRef );
    CFRelease( productIDCFNumRef );
CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    CFNumberRef vendorIDCFNumRef  = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &vendorId );
    CFNumberRef productIDCFNumRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &productId );

    CFDictionarySetValue( matchDict, CFSTR( kIOHIDVendorIDKey  ), vendorIDCFNumRef );
    CFDictionarySetValue( matchDict, CFSTR( kIOHIDProductIDKey ), productIDCFNumRef );

    CFRelease( vendorIDCFNumRef );
    CFRelease( productIDCFNumRef );
现在,我看到了不同的堆栈跟踪,从CFRunLoop调用,尽管我仍然在符号中看到GetTypeID

0x00007fff8534407a  <+0023>  jne    0x7fff8534409f <IOHIDDeviceScheduleWithRunLoop+60>
0x00007fff8534407c  <+0025>  mov    0x18(%rdi),%rdi
0x00007fff85344080  <+0029>  mov    (%rdi),%rax
0x00007fff85344083  <+0032>  lea    0x58(%r12),%rsi
0x00007fff85344088  <+0037>  callq  *0x40(%rax)
0x00007fff8534408b  <+0040>  test   %eax,%eax
0x00007fff8534408d  <+0042>  jne    0x7fff85344148 <IOHIDDeviceScheduleWithRunLoop+229>
0x00007fff85344093  <+0048>  cmpq   $0x0,0x58(%r12)
0x00007fff85344099  <+0054>  je     0x7fff85344148 <IOHIDDeviceScheduleWithRunLoop+229>
0x00007fff8534409f  <+0060>  mov    0x58(%r12),%rdi
0x00007fff853440a4  <+0065>  callq  0x7fff85368f36 <dyld_stub_CFGetTypeID>
0x00007fff853440a9  <+0070>  mov    %rax,%rbx
0x00007fff853440ac  <+0073>  callq  0x7fff85369008 <dyld_stub_CFRunLoopSourceGetTypeID>
0x00007fff853440b1  <+0078>  cmp    %rax,%rbx
0x00007fff853440b4  <+0081>  jne    0x7fff853440cc <IOHIDDeviceScheduleWithRunLoop+105>
0x00007fff8534407a jne 0x7fff8534409f
0x00007fff8534407c mov 0x18(%rdi),%rdi
0x00007fff85344080 mov(%rdi),%rax
0x00007fff85344083 lea 0x58(%r12),%rsi
0x00007fff85344088 callq*0x40(%rax)
0x00007fff8534408b测试%eax,%eax
0x00007fff8534408d jne 0x7fff85344148
0x00007fff85344093 cmpq$0x0,0x58(%r12)
0x00007fff85344099 je 0x7fff85344148
0x00007fff8534409f mov 0x58(%r12),%rdi
0x00007fff853440a4呼叫0x7fff85368f36
0x00007fff853440a9移动百分比rax,%rbx
0x00007fff853440ac呼叫0x7fff85369008
0x00007fff853440b1 cmp%rax,%rbx
0x00007fff853440b4 jne 0x7fff853440cc
我看到它在0x00007fff85344080 mov(%rdi),%rax处断开,用于IOHIDDeviceScheduleWithRunLoop(请使用0x00007fff85344080搜索)

在参考文档的帮助下,我看到它是第一个参数,表示tIOHIDManagerRef,我创建了IOHIDManagerRef tIOHIDManagerRef=IOHIDManagerCreate(kcfalocatordefault,kIOHIDOptionsTypeNone)


但是,如何从堆栈跟踪上方查看它的地址?

哪一行生成异常?堆栈是什么?CFRunLoopRun();(我还看到了在堆栈跟踪中CFRunLoop调用CFGetTypeID)堆栈包含第一个代码块的方法,然后是CFRunLoop,然后是CFGetTypeID。哪一行生成了异常?堆栈是什么?CFRunLoopRun();(我还看到了在堆栈跟踪中CFRunLoop调用CFGetTypeID)堆栈包含第一个代码块的方法,然后是CFRunLoop,然后是CFGetTypeID。如果我打开NSZombie,它可以工作,但在控制台中看不到任何日志或在工具中看不到任何消息。因此,这就离开了调试器。检查要传递给CFGetType的对象的地址,并将其与您知道的对象进行比较。请检查我的其他响应。您可以告诉我如何检查堆栈跟踪中的地址吗?堆栈跟踪中没有地址。您需要在调试器中检查它,如上面的“检查gdb中的Obj-C参数”链接中所述。如果我打开NSZombie,它可以工作,但在控制台中看不到任何日志或仪器中没有任何消息。因此,调试器将离开。检查要传递到的对象的地址