【问题标题】:C Callback in Objective-C (IOKIT)Objective-C 中的 C 回调 (IOKIT)
【发布时间】:2011-10-16 03:57:35
【问题描述】:

我正在尝试在 Objective C 中编写一些与 USB 设备交互的代码,但在为传入报告设置回调函数时遇到了困难。就我而言,它是一个 IOKIT 函数,但我认为这个问题更普遍,因为我(显然)不知道如何在 Objective-C 中正确设置 C 回调函数。我有一个处理 io 函数的“USBController”类

USBController.m:

#include <CoreFoundation/CoreFoundation.h>
#include <Carbon/Carbon.h>
#include <IOKit/hid/IOHIDLib.h>
#import "USBController.h"

static void Handle_IOHIDDeviceIOHIDReportCallback(
                                              void *          inContext,          // context from IOHIDDeviceRegisterInputReportCallback
                                              IOReturn        inResult,           // completion result for the input report operation
                                              void *          inSender,           // IOHIDDeviceRef of the device this report is from
                                              IOHIDReportType inType,             // the report type
                                              uint32_t        inReportID,         // the report ID
                                              uint8_t *       inReport,           // pointer to the report data
                                              CFIndex         InReportLength)     // the actual size of the input report
{
    printf("hello"); //just to see if the function is called
}

@implementation USBController
- (void)ConnectToDevice {
    ...
    IOHIDDeviceRegisterInputReportCallback(tIOHIDDeviceRefs[0], report, reportSize,
          Handle_IOHIDDeviceIOHIDReportCallback,(void*)self);
    ...
}
...
@end

所有的函数也在头文件中声明。

我认为我所做的与我发现的 here 几乎相同,但它不起作用。该项目编译良好,一切正常,直到有输入和回调函数被调用。然后我收到“EXC_BAD_ACCESS”错误。函数的前三个参数是正确的。我不太确定上下文.. 我做错了什么?

【问题讨论】:

    标签: objective-c c callback hid iokit


    【解决方案1】:

    我完全不确定您的 EXEC_BAD_ACCESS 是否取决于您的回调。确实,如果你说它被调用了(我想你会看到日志)并且由于它只记录一条消息,那么这应该没有问题。

    EXEC_BAD_ACCESS 是由试图访问已释放的对象引起的。您可以通过两种方式获取更多信息:

    1. 在调试模式下执行程序,所以当它崩溃时你将能够看到堆栈内容;

    2. 激活 NSZombies 或使用性能工具 Zombies 运行程序;这将准确告诉您在释放后访问了哪个对象。

    【讨论】:

    • 好吧,它没有被调用。没有日志消息。我应该如何调试这个?僵尸没有给我任何线索,没有检测到僵尸对象。我应该在堆栈内容中寻找什么?显示如下:#0 0x7fffffe007c5 in __memcpy 我猜它试图将某些东西复制到一个不存在的对象中?但是我怎样才能弄清楚哪里出了问题?
    • 如果您可以看到堆栈跟踪,那么您就看不到最后调用的函数。从你说的,我唯一能想到的是report没有预分配,但你说是,所以不应该是这样的......无论如何,程序如何调用__memcpy(堆栈trace) 这可以给你一个提示
    • 嗯,我想不通。我在这里发布了完整的代码link,这可能会澄清一些事情。无论如何感谢您的努力。
    • 您是否会尝试安排设备设置回调之后,例如在IOHIDDeviceSetReport 之前?尝试删除回调并看看会发生什么?增加report 大小?我真的没有其他想法......
    【解决方案2】:

    我知道如何解决这个问题。调用时:

    IOHIDDeviceRegisterInputReportCallback(tIOHIDDeviceRefs[0], report, reportSize,
              Handle_IOHIDDeviceIOHIDReportCallback,(void*)self);
    

    您没有包含用于创建/类型称为报告的值的代码。但是,方法名称“Handle_IOHIDDeviceIOHIDReportCallback”来自 Apple 文档,其中在创建报告值时出错。 https://developer.apple.com/library/archive/technotes/tn2187/_index.html

    CFIndex reportSize = 64; 
    uint8_t report = malloc( reportSize );  // <---- WRONG 
    IOHIDDeviceRegisterInputReportCallback( deviceRef, 
                                            report,  
                                            reportSize,
                                            Handle_IOHIDDeviceIOHIDReportCallback,   
                                            context ); 
    

    改为这样做:

    uint8_t *report = (uint8_t *)malloc(reportSize);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-21
      • 2016-06-25
      • 2013-08-18
      • 1970-01-01
      • 2018-12-13
      • 1970-01-01
      • 2013-01-22
      相关资源
      最近更新 更多