Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用ctypes从CoreFoundation调用带有参数的函数_Python_Macos_Ctypes_Coremidi - Fatal编程技术网

Python 使用ctypes从CoreFoundation调用带有参数的函数

Python 使用ctypes从CoreFoundation调用带有参数的函数,python,macos,ctypes,coremidi,Python,Macos,Ctypes,Coremidi,我正在尝试使用Python中的ctypes从MacOSX中的CoreFoundation框架访问CoreMidi函数 当我调用一个没有任何参数的函数时,一切都很顺利。例如,以下代码: from ctypes import * core_midi = cdll.LoadLibrary("/System/Library/Frameworks/CoreMIDI.framework/Versions/A/CoreMIDI") numOfDevices = core_midi.MIDIGetNumberO

我正在尝试使用Python中的ctypes从MacOSX中的CoreFoundation框架访问CoreMidi函数

当我调用一个没有任何参数的函数时,一切都很顺利。例如,以下代码:

from ctypes import *
core_midi = cdll.LoadLibrary("/System/Library/Frameworks/CoreMIDI.framework/Versions/A/CoreMIDI")
numOfDevices = core_midi.MIDIGetNumberOfDevices()
print numOfDevices
返回

3
这是我的计算机中MIDI设备的数量

但是,我无法执行需要参数的函数。检查此示例(EDIT:正如eryksun指出的,我使用了char*作为客户端名称,函数原型要求使用CFString。我在下面的代码示例中更正了这一点,但仍然得到相同的错误):

这段代码根本不打印任何内容,甚至不会引发异常。midclientcreate函数的原型是:

extern OSStatus MIDIClientCreate(
    CFStringRef name, 
    MIDINotifyProc notifyProc, 
    void *notifyRefCon, 
    MIDIClientRef *outClient );  
MIDIClientRef被定义为UInt32,据我所知,它接收指向已创建的MIDIClient结构的指针,这就是我使用byref()将其作为参数传递的原因。如果我只传递不带byref()的变量,函数调用将返回一个值-50,这可能表示出现了一些奇怪的错误

编辑:我不确定是否正确创建了CFString。我试图用下面的代码测试结果,但它没有在屏幕上打印任何内容

client_name = core_foundation.CFStringCreateWithCString(None, "MIDI Client", 0)
cstr = ctypes.create_string_buffer(20)
core_foundation.CFStringGetCString(client_name, cstr, 20, 0)
print cstr
谢谢

编辑:由艾尔克森回答

当然,我不知道这一点,但设置指针并不像我天真的例子那样明显

class _CFString(Structure):
    pass

cf_path = ctypes.util.find_library("CoreFoundation")
cm_path = ctypes.util.find_library("CoreMIDI")

core_foundation = ctypes.cdll.LoadLibrary(cf_path)
core_midi = ctypes.cdll.LoadLibrary(cm_path)

CFStringRef = POINTER(_CFString)

midi_client = ctypes.c_uint()
core_foundation.CFStringCreateWithCString.restype = CFStringRef
core_foundation.CFStringCreateWithCString.argtypes = [c_void_p, c_char_p, c_uint32]
client_name = core_foundation.CFStringCreateWithCString(None, "MIDI Client", 0)

core_midi.MIDIClientCreate.argtypes = [CFStringRef, c_void_p, c_void_p, POINTER(c_uint32)]    
result = core_midi.MIDIClientCreate(client_name, None, None, byref(midi_client))

print midi_client
print result
实际上,我认为restype和argtypes不会影响函数的执行方式或参数的传递方式,但它们似乎确实会影响

上述代码导致:

c_uint(4657178L)
0
也就是说,我的MIDI客户机是在某处创建的,函数返回时不会出错。
再次感谢埃里克森

哦,好的,艾里克森。我尝试使用CFStringCreateWithBytes创建CFString,但仍然没有成功。为了反映这一点,我对问题进行了编辑。我想我搞乱了byref参数…嘿,eryksun,就是这样,非常感谢!写一个答案,这样我就可以把你标记为回答者。顺便说一句,只需重新设置样式就足够了。。。我认为您对64位结果指针被截断的看法是正确的。。。
c_uint(4657178L)
0