tags:

views:

183

answers:

2

Hi,

I am struggling to implement an HID control with a Mac : I cannot send the expected function as depicted here below:

IOHIDManagerRegisterDeviceMatchingCallback( gIOHIDManagerRef, Handle_DeviceMatchingCallback, NULL );

with : gIOHIDManagerRef -> the valid HID manager dedicated to this routine Handle_DeviceMatchingCallback --> the routine that will be called back when the HID device is attached to the USB port NUUL --> not used here, contain data from the USB The issue is that Handle_DeviceMatchingCallback must be a pointer to the routine, but how can I send a pointer ? On the other hand, all the examples , from the Apple source, are based on C, not on cocoa. Well, does that means that I must rework my program in C ??? Or is it possible to have fraction of the program in C under the cocoa environment? Sorry for so "stupid" question queries, but, although I have some background in the field of electronic an programming, I am very newbees with cocoa. Your comments will be very appreciated !

Michael

+1  A: 

Handle_DeviceMatchingCallback must be a pointer to the routine, but how can I send a pointer ?

If you want to pass in a function functionName, you can pass it as &functionName.

On the other hand, all the examples , from the Apple source, are based on C, not on cocoa. Well, does that means that I must rework my program in C ??? Or is it possible to have fraction of the program in C under the cocoa environment?

You can mix C and Objective-C at will. As long as you pass it a function, and not a method attached to an object, it should work.

LnxPrgr3
A: 

Objective-C is mostly a super-set of C. In order to combine C and Objective-C code, you simply compile your C code as if it were Objective-C code. The easiest way to do this in Xcode is to ensure the file in question has a .m extension.

To route handling back to the Objective-C world, you need a pointer to an Obj-C object. Many callback-based APIs allow you to provide a generic pointer (void *) that they then pass back to you when they callback. This argument has several common names:

  • context or ctx
  • refcon (for "reference constant")
  • userData
  • userInfo

If the callback API does not allow this, you'll need some uglier way to dispatch the callback to your object, such as a global pointer or a lookup table.

The API you're using does let you provide a context pointer. When it calls back to your code, it provides you with the pointer you used when you registered for the callback. Here is an example of registering the callback from an object of type MyObjCClass (see the -registerMatching method below) and then using the context pointer to route the callback back to the object that registered the callback for handling (see the Handle_DeviceMatchingCallback function's use of the context pointer).

/*! @file C-ObjC-Callbacks.m
 *  Demonstrates routing a C callback to an Obj-C object
 *  using the callback's context pointer.
 */
#import <Cocoa/Cocoa.h>
#import <IOKit/hid/IOHIDManager.h>

// Global HID manager reference.
IOHIDManagerRef gIOHIDManager;
// HID callback
void Handle_DeviceMatchingCallback(void *context,
                                   IOReturn result,
                                   void *sender,
                                   IOHIDDeviceRef device);

@interface MyObjCClass : NSObject {
}
- (void)registerMatching;
- (void)handleMatchingDevice:(IOHIDDeviceRef)device
                      sender:(void *)sender
                      result:(IOReturn)result;
@end

@implementation MyObjCClass
- (void)registerMatching {
  // Assume gIOHIDManager has already been created.
  // Set up a device matching callback, providing a pointer to |self| as the context.
  IOHIDManagerRegisterDeviceMatchingCallback(gIOHIDManager,
                                             Handle_DeviceMatchingCallback,
                                             (void *)self);
}

- (void)handleMatchingDevice:(IOHIDDeviceRef)device
                      sender:(void *)sender
                      result:(IOReturn)result {
  // Do something...
}
@end

void
Handle_DeviceMatchingCallback(void *context,
                              IOReturn result,
                              void *sender,
                              IOHIDDeviceRef device); {
  MyObjCClass *const myObject = (MyObjCClass *const)context;
  [myObject handleMatchingDevice:device sender:sender result:result];
}
Jeremy W. Sherman