Обратный вызов C в Objective-C (IOKIT) - PullRequest
2 голосов
/ 29 июля 2011

Я пытаюсь написать некоторый код, который взаимодействует с USB-устройством в Objective C, и я застрял при настройке функции обратного вызова для входящих отчетов. В моем случае это функция IOKIT, но я думаю, что проблема более общая, поскольку я (по-видимому) не знаю, как правильно установить функцию обратного вызова C в Objective-C. У меня есть класс "USBController", который обрабатывает функции IO

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

Все функции также объявлены в заголовочном файле.

Я думаю, я сделал почти то же самое, что нашел здесь , но это не работает. Проект хорошо компилируется, и все работает до тех пор, пока не будет введен ввод и не будет вызвана функция обратного вызова. Затем я получаю ошибку «EXC_BAD_ACCESS». Первые три аргумента функции верны. Я не так уверен насчет контекста .. Что я сделал не так?

Ответы [ 2 ]

4 голосов
/ 29 июля 2011

Я совсем не уверен, что ваш EXEC_BAD_ACCESS зависит от вашего обратного вызова. В самом деле, если вы говорите, что он вызывается (я полагаю, вы видите журнал), и поскольку он только регистрирует сообщение, с этим не должно быть проблем.

EXEC_BAD_ACCESS вызван попыткой доступа к уже освобожденному объекту. Вы можете получить больше информации двумя способами:

  1. запустить программу в режиме отладки, поэтому при ее сбое вы сможете увидеть содержимое стека;

  2. активировать NSZombies или запустить программу с помощью инструмента повышения производительности Zombies; это точно скажет вам, к какому объекту обращались после его освобождения.

0 голосов
/ 24 января 2019

Я знаю, как это исправить. При звонке это:

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);
...