使用ctypes从回调函数访问结构参数

时间:2014-04-07 22:12:10

标签: python macos callback ctypes coremidi

我使用MacOSX的CoreMIDI函数访问计算机中的MIDI设备。此外,我想用Python和ctypes来做。

为了做到这一点,我必须创建一个回调函数,只要我的计算机收到MIDI消息就会调用它。回调原型(在C中)是:

typedef void ( *MIDIReadProc)(
const MIDIPacketList *pktlist,
void *readProcRefCon,
void *srcConnRefCon);

MIDIPacketList定义为:

struct MIDIPacketList { 
UInt32 numPackets; 
MIDIPacket packet[1]; 
};

MIDIPacket定义为:

struct MIDIPacket { 
MIDITimeStamp timeStamp; 
UInt16 length; 
Byte data[256]; 
};

MIDITimeStamp定义为:

typedef UInt64 MIDITimeStamp;

好的,我的定义回调和自定义结构的代码如下:

MIDITimeStamp = c_ulonglong

class MIDIPacket(Structure):
    _fields_ = [("timeStamp", MIDITimeStamp),
                ("length", c_ushort),
                ("data", c_char_p)]

class MIDIPacketList(Structure):
    _fields_ = [("numPackets", c_uint),
                ("packet", POINTER(MIDIPacket))]

def callback(midi_packet_list, proc_ref, src_ref):
    m_pack_list = midi_packet_list.contents
    packet = m_pack_list.packet.contents
    print packet.length     # This line crashes the program

CALLBACKFUNC = CFUNCTYPE(None, POINTER(MIDIPacketList), c_void_p, c_void_p)
midi_input_callback = CALLBACKFUNC(callback)

# I omitted the MIDI setup code because I don't think it is relevant here

# MIDIInputPortCreate associates the callback function to the midi endpoint and input port
result = core_midi.MIDIInputPortCreate(midi_client, input_port_name, midi_input_callback, None, byref(input_port));

我不知道为什么,但我无法正确访问回调函数中midi_packet_list指向的数据。这应该是指向MIDIPacketList结构的指针,我将其与midi_packet_list.contents取消引用。然后我尝试获取参数packet [0],它应该是MIDIPacketObject。但是当我尝试访问MIDIPacket数据(packet.length)时,程序崩溃了。

我知道回调被正确调用,因为当我的MIDI设备关闭时,它永远不会被调用,但是当MIDI设备打开时,我可以在屏幕上打印信息。但是我无法从MIDIPacketList访问数据,这是回调例程中最重要的部分。我需要有人帮我指出访问这些数据的正确方法。

谢谢!

0 个答案:

没有答案