2

查看 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模块,并指定了argtypesandrestype等,并且工作正常,但它在与 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),我想我会在这里问一下,看看是否有人已经这样做了(或者对此主题有任何其他热门想法。)

4

0 回答 0