2

Looking at PyObjC I see that there is some support for pulling in C API functions that operate on CF <-> Objective-C bridged types from the *.bridgesupport files in frameworks (i.e. _setupCFClasses in the objc module.)

What I'm curious about is whether anyone has implemented support for bringing in ALL the C functions in the *.bridgesupport file. For instance, if I try to pull in IOKit.framework, by doing something like this:

import objc as _objc
foo = _objc.initFrameworkWrapper("IOKit",
                     frameworkIdentifier="com.apple.framework.IOKit",
                     frameworkPath=_objc.pathForFramework("/System/Library/Frameworks/IOKit.framework"),
                     globals=globals())

It's clear that it's using the bridge support file enclosed in the IOKit.framework -- I end up with all the constants declared in that bridgesupport file being put into globals -- but it doesn't seem like I get much else, presumably because PyObjC is looking for Objective-C class declarations, and not finding any. That bridgesupport file contains descriptions for all of the IOKitLib C functions (like IORegistryEntryFromPath, etc.) many of which accept and/or return various CFTypes (some of which are bridged to Objective-C types).

I wanted to whip up a Python script that called some of these IOKit functions, and I ended up using the ctypes module, and specifying argtypes and restype, etc. and that worked, but it fell down in terms of integrating with Objective-C types. Take IORegistryEntryCreateCFProperties for example:

# set up the types
mach_port_t = ctypes.c_long;
io_registry_entry_t = mach_port_t;
iokit = ctypes.cdll.LoadLibrary('/System/Library/Frameworks/IOKit.framework/IOKit')    
iokit.IORegistryEntryCreateCFProperties.argtypes = [io_registry_entry_t, ctypes.POINTER(ctypes.c_void_p), ctypes.c_void_p, ctypes.c_uint32 ]
iokit.IORegistryEntryCreateCFProperties.restype = ctypes.c_int
# Call it
propDict = ctypes.c_void_p()
iokit.IORegistryEntryCreateCFProperties(regEntry, propDict, 0, 0)

That's great, and propDict is now a pointer to a CFMutableDictionaryRef but I can't use it in Python like I could an NSDictionary that came from a call brokered by PyObjC (in my script I ended up bringing in all the C API necessary to do what I needed using ctypes). I see that newer versions of PyObjC have support for creating PyObjC wrappers from a c_void_p (ignoring for the moment that this feature doesn't appear to be in the version of PyObjC shipping with MacOS), but what I'd really like (you know, aside from a pony) is for all this stuff, including the functions themselves, to have been "stitched up" by the process that reads and integrates the *.bridgesupport file.

I'm a Python amateur (but an ObjC veteran), so I recognize that this might be a non-trivial piece of functionality to implement, and I can also see how it could be argued that it's outside the purview of PyObjC (since the API in question is a straight-C API, only some methods of which take/return bridged CFTypes), but it also seems like something that would be logical to do, so before I spend a bunch of time trying to do it (while simultaneously learning Python), I figured I'd ask here and see if anyone already did it (or had any other hot ideas on the topic.)

ipmcc
  • 29,581
  • 5
  • 84
  • 147
  • The system-included PyObjC .bridgesupport files famously lag behind the libraries themselves. Does the existing bridge support file actually mention the functions you're looking to include? Have you tried creating your own version (by editing the original) with the missing info? IIRC, PyObjC should prefer a local version (same directory as your script) of IOKit.bridgesupport to the system version. Two old answers of mine might have some useful info for you about editing the bridge support data: http://stackoverflow.com/a/5336824/, http://stackoverflow.com/a/5271245/ – jscs Oct 03 '13 at 22:42

0 Answers0