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

2024-10-16 17:16:13 发布

您现在位置:Python中文网/ 问答频道 /正文

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

为了做到这一点,我必须创建一个回调函数,每当我的计算机接收到MIDI消息时都会调用该函数。回调原型(在C中)是:

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

MIDIPacketList定义为:

^{pr2}$

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[0],它应该是一个midpackketObject。但是当我试图访问MIDIPack数据时(数据包长度)程序崩溃。在

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

谢谢!在


Tags: the数据函数input定义packetcallbacklength