查看 PyObjC,我发现有一些支持从框架中的 *.bridgesupport 文件(即模块中)_setupCFClasses
中提取对 CF <-> Objective-C 桥接类型进行操作的 C API 函数。objc
我很好奇的是是否有人实现了对在 *.bridgesupport 文件中引入所有 C 函数的支持。例如,如果我尝试通过执行以下操作来引入 IOKit.framework:
import objc as _objc
foo = _objc.initFrameworkWrapper("IOKit",
frameworkIdentifier="com.apple.framework.IOKit",
frameworkPath=_objc.pathForFramework("/System/Library/Frameworks/IOKit.framework"),
globals=globals())
很明显,它使用的是包含在 IOKit.framework 中的桥支持文件——我最终将在该桥支持文件中声明的所有常量都放入其中globals
——但我似乎没有得到太多其他东西,大概是因为 PyObjC 是寻找 Objective-C 类声明,但没有找到。该 bridgesupport 文件包含对所有 IOKitLib C 函数(如IORegistryEntryFromPath
等)的描述,其中许多函数接受和/或返回各种 CFType(其中一些桥接到 Objective-C 类型)。
我想编写一个调用其中一些 IOKit 函数的 Python 脚本,我最终使用了该ctypes
模块,并指定了argtypes
andrestype
等,并且工作正常,但它在与 Objective-C 类型的集成方面失败了。举个IORegistryEntryCreateCFProperties
例子:
# 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)
太好了,propDict 现在是一个指向 a 的指针,CFMutableDictionaryRef
但我不能像我一样在 Python 中使用它,它NSDictionary
来自 PyObjC 代理的调用(在我的脚本中,我最终引入了执行我所做的所有必要的 C API需要使用ctypes
)。我看到较新版本的 PyObjC支持从c_void_p
除了小马),所有这些东西,包括函数本身,都是由读取和集成 *.bridgesupport 文件的进程“缝合”的。
我是 Python 爱好者(但也是 ObjC 的老手),所以我认识到这可能是一个很重要的功能实现,而且我还可以看到如何认为它超出了 PyObjC 的范围(因为有问题的 API 是一个直接 C API,只有一些方法采用/返回桥接 CFTypes),但这似乎也是合乎逻辑的事情,所以在我花很多时间尝试这样做之前(同时学习 Python),我想我会在这里问一下,看看是否有人已经这样做了(或者对此主题有任何其他热门想法。)