Advertisement Jump to content
  • Advertisement
Sign in to follow this  
  • entries
  • comments
  • views


Sign in to follow this  


I'm about ready to give up on OSX programming, reconnect my PC, and let the Mac collect dust for the next month. Take a look at this little bit of code I wrote for retrieving an interface to a HID device:

// m_pxGenericInterface is an IOCFPlugInInterface* member of the class
// m_xHIDDevice is an io_object_t member of the class
// m_pxDeviceInterface is an IOHIDDeviceInterface* member of the class

io_name_t className;
HRESULT plugInResult = S_OK;
SInt32 score = 0;
IOReturn ioReturnValue;
IOCFPlugInInterface** ppxGenericInterfacePtr = &m_pxGenericInterface;

ioReturnValue = IOObjectGetClass(m_xHIDDevice, className);
ASSERT(ioReturnValue == kIOReturnSuccess, "Couldn't get class name");

ioReturnValue = IOCreatePlugInInterfaceForService(m_xHIDDevice, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &ppxGenericInterfacePtr, &score);
ASSERT(ioReturnValue == kIOReturnSuccess, "Couldn't create plugin interface");
ASSERT(m_pxGenericInterface, "Generic plugin interface is null");

plugInResult = m_pxGenericInterface->QueryInterface(m_pxGenericInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), &m_pxDeviceInterface);
ASSERT(SUCCEEDED(plugInResult), "Couldn't get HID interface");
ASSERT(m_pxDeviceInterface, "Device interface is null");

Yeah. I'm not sure what the classname code is for, but it's in the samples so I'm keeping it till it works. Anyway, this code crashes. Not due to an assertion failure - I wrote an assertion handler such that I can hit 'ignore' on an assertion anyway - but on the last main line:

plugInResult = m_pxGenericInterface->QueryInterface(m_pxGenericInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), &m_pxDeviceInterface);

Looks innocuous enough, right? It throws an access violation ('EXC_BAD_ACCESS').

COM programmers may be thinking, 'hang on, this looks a bit familiar.' It should - it's COM, on Mac. Except that rather than doing things as a Windows programmer would be used to - i.e. using classes - they're sticking with C, which means that all COM interfaces are actually structures. Which is somewhat suck.

Anyway, I don't know why that call fails. The assertion on the line before doesn't fail, so the interface pointer isn't null; it's a standard QueryInterface call, with the interface ID to query and the address to store the result into. Breakpointing on the line before to check out the pxGenericInterface data doesn't suggest anything totally fucked (like QueryInterface being null or something), so I really just don't know why it's failing. What is QueryInterface trying to do internally?

I've tried stepping through the code in the disassembler, and while I'm somewhat hindered by the fact that I don't know Apple assembly, it looks like it crashes when it first tries to perform a jump, which suggests that the value of QueryInterface is wrong. Why? Why is it wrong? How do I fix it?

If you know the answer, please write to the programme at the following address:

Leave a Comment

Edit: OK, I fixed it with the help of the iDevGames folks. It seems that Core Foundation doesn't trust you with fullblown COM - it wants to pretend that COM objects are still Core Foundation objects, and so like everything else in Core Foundation, it will keep the object and you will get a pointer to it. This includes interfaces to COM objects - so CF has the interface (a pointer to a structure) and I get a pointer to it (a pointer to a pointer to a structure). This makes my calls somewhat stupid - (*pxInterface)->Somefunction() - but I can live with it. It doesn't crash anymore, at least.

On a side note, this would all have been prevented if it weren't for those horrible void* types on the CF functions. [sad]
Sign in to follow this  

1 Comment

Recommended Comments

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!