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