我想用Python调用IOKit框架。
这是我要调用的Objective-C函数的签名:
IOReturn IODisplayGetFloatParameter(io_service_t service, IOOptionBits options, CFStringRef parameterName, float *value);
使用pyObjc
,在导入后,我将执行以下操作:
brightness = 0.0
IODisplayGetFloatParameter(service, 0, kIODisplayBrightnessKey, brightness)
但是,出现此错误:
ValueError: depythonifying 'pointer', got 'float'
这是BridgeSupport文件的相关位,pyObjc
正在IOKit.IODisplayGetFloatParameter()
上生成句柄:
<function name='IODisplayGetFloatParameter'>
<arg type='I'/>
<arg type='L' type64='I'/>
<arg type='^{__CFString=}'/>
<arg type='^f'/>
<retval type='i'/>
这使我相信我需要创建pyObjc
对象,该对象表示一个指向float
的指针,但是我很难找到相关的文档来做到这一点。
因此,我尝试使用ctypes
,但是它存在段错误,因为我没有赋予它正确的argtypes
或将正确的值传递给函数。
from ctypes import CDLL, c_void_p, byref, c_char_p, c_int, c_float, pointer, POINTER
from ctypes.utils import find_library
c_float_p = POINTER(c_float)
float_ptr = c_float_p(c_float(0.0))
IOKit = CDLL(find_library('IOKit'))
IOKit.IODisplaySetFloatParameter.argtypes = [c_int, c_int, c_char_p, c_float_p]
IOKit.IODisplaySetFloatParameter(service_goes_here, 0, "brightness", float_pointer)
Segmentation fault: 11
谁能指出我的方向:
pyObjc
包装的函数吗?ctypes
呼叫IODisplayGetFloatParameter
吗?答案 0 :(得分:0)
这里的问题是网桥支持文件不完整(可悲的是,大多数系统网桥支持文件都不够)。
以下代码更有效地展示了此功能:
import objc
bundle = objc.loadBundle('IOKit', bundle_path='/System/Library/Frameworks/IOKit.framework', module_globals=globals())
objc.objc.loadBundleFunctions(bundle, globals(), [
(
'IODisplayGetFloatParameter',
objc._C_INT + objc._C_UINT + objc._C_NSUInteger + objc._C_ID + objc._C_PTR + objc._C_FLT,
'',
{ 'arguments': { 3: { 'type_modifier': b'n' }}} ),
])
print(IODisplayGetFloatParameter.__metadata__())
这假定IODisplayGetFloatParameter通过引用返回单个浮点值。