Treating structure as character array?

Peter Parente <[email protected]> Sat, 10 Jan 2004 11:46:22 -0500
Newsgroups gmane.comp.python.ctypes.devel
Message-ID <[email protected]>
Hi,

I'm trying to get a wrapper using ctypes working around the windows MIDI 
streaming functions. The relevant structures in C are the following:

typedef struct midihdr_tag {
    LPSTR       lpData;               /* pointer to locked data block */
    DWORD       dwBufferLength;       /* length of data in data block */
    DWORD       dwBytesRecorded;      /* used for input only */
    DWORD_PTR   dwUser;               /* for client's use */
    DWORD       dwFlags;              /* assorted flags (see defines) */
    struct midihdr_tag far *lpNext;   /* reserved for driver */
    DWORD_PTR   reserved;             /* reserved for driver */
#if (WINVER >= 0x0400)
    DWORD       dwOffset;             /* Callback offset into buffer */
    DWORD_PTR   dwReserved[8];        /* Reserved for MMSYSTEM */
#endif
} MIDIHDR, *PMIDIHDR, NEAR *NPMIDIHDR, FAR *LPMIDIHDR;

typedef struct midievent_tag
{
    DWORD       dwDeltaTime;          /* Ticks since last event */
    DWORD       dwStreamID;           /* Reserved; must be zero */
    DWORD       dwEvent;              /* Event type and parameters */
    DWORD       dwParms[1];           /* Parameters if this is a long 
event */
} MIDIEVENT;

I've interpreted these in Python using ctypes as:

class MIDIEVENT(Structure):
  _fields_ = [("dwDeltaTime", c_ulong),
    ("dwStreamID", c_ulong),
    ("dwEvent", c_ulong),
    ("dwParams", c_ulong * 1)]

lpMidiHdr = POINTER("MIDIHDR")
class MIDIHDR(Structure):
  _fields_ = [("lpData", c_char_p),
    ("dwBufferLength", c_ulong),
    ("dwBytesRecorded", c_ulong),
    ("dwUser", POINTER(c_ulong)),
    ("dwFlags", c_ulong),
    ("lpNext", lpMidiHdr),
    ("reserved", POINTER(c_ulong)),
    ("dwOffset", c_ulong),
    ("dwReserved", POINTER(c_ulong * 8))]

The problem I'm having is with the lpData field in the MIDIHDR 
structure. It expects an array of MIDIEVENT structures, but ctypes 
doesn't like it if I just do the following:

  # create a header object
  header = MIDIHDR()
 
  # create an event and put it into the header
  event = MIDIEVENT()
  event.dwEvent = MidiOutMsg(0x90, 0, 69, 127)
   
  header.lpData = pointer(event)

Is it possible to assign an event or array of events to the lpData field 
as a pointer to char? As an alternative, I see that I might have to 
ditch the event structure altogether, and just build the lpData string 
from scratch. How could I go about doing that? Should I use c_buffer, 
and, if so, how do you represent its type in the structure?

I'm not sure where to go from here, so any help will be appreciated.

Pete


-------------------------------------------------------
This SF.net email is sponsored by: Perforce Software.
Perforce is the Fast Software Configuration Management System offering
advanced branching capabilities and atomic changes on 50+ platforms.
Free Eval! http://www.perforce.com/perforce/loadprog.html