ctypes, error when calling function

M

Max M

Trying to write realtime midi in Windows I am using ctypes. So I have
written a small wrapper for winmm.dll

It partly works. I get this error when I try to run it:

Traceback (most recent call last):
File "E:\maxm\pys\MIDI-R~1\x.py", line 203, in ?
print winmm.midiOutGetDevCaps(deviceID, caps, sizeof(caps))
File "E:\maxm\pys\MIDI-R~1\x.py", line 133, in __getattr__
return getattr(self._winmm, attr)
File "C:\pytyons\Python23\Lib\site-packages\ctypes\__init__.py", line
316, in __getattr__
func = self._StdcallFuncPtr(name, self)
AttributeError: function 'midiOutGetDevCaps' not found

But the documentation says that the midiOutGetDevCaps() should exist in
the dll.

It calls the midiOutGetNumDevs() function in the dll nicely, wich is why
I find it to be strange problem.

Does anybody have a clue? It's my first try at ctypes, so I am a bit
lost here.

regards Max M


#################################3
# The code

from ctypes import *

MAXPNAMELEN = 32

class MIDIOUTCAPS(Structure):
_fields_ = [
("wMid", c_int), # WORD
("wPid", c_int), # WORD
("vDriverVersion", c_long), # MMVERSION
("szPname", c_char * MAXPNAMELEN), # CHAR
("wTechnology", c_int), # WORD
("wVoices", c_int), # WORD
("wNotes", c_int), # WORD
("wChannelMask", c_int), # WORD
("dwSupport", c_long), # DWORD
]


class Winmm:

"""A *very* thin wrapper over WINMM.DLL :)
"""

def __init__(self):
self._winmm = windll.WINMM

def __getattr__(self, attr):
return getattr(self._winmm, attr)



if __name__ == '__main__':

caps = MIDIOUTCAPS()
winmm = Winmm()
numDevs = winmm.midiOutGetNumDevs()
for deviceID in range(-1, numDevs):
print winmm.midiOutGetDevCaps(deviceID, caps, sizeof(caps))






--

hilsen/regards Max M, Denmark

http://www.mxm.dk/
IT's Mad Science
 
R

Richie Hindle

AttributeError: function 'midiOutGetDevCaps' not found

Like a lot of Windows APIs, midiOutGetDevCaps exists in both ANSI and
Unicode variants. You need to call midiOutGetDevCapsA or
midiOutGetDevCapsW according to whether you're using ANSI or Unicode.

Because you're using c_char in your MIDIOUTCAPS structure:
("szPname", c_char * MAXPNAMELEN)

you need to call the ANSI variant, midiOutGetDevCapsA.

When you're programming Windows in C, the API header files define
midiOutGetDevCaps to be either midiOutGetDevCapsA or midiOutGetDevCapsW
according to whether you're compiling an ANSI or Unicode application.
This is why any C-based sample code you might see doesn't have this
problem.
 
M

Max M

Richie said:
Like a lot of Windows APIs, midiOutGetDevCaps exists in both ANSI and
Unicode variants. You need to call midiOutGetDevCapsA or
midiOutGetDevCapsW according to whether you're using ANSI or Unicode.

Ah, ok. That nailed it.
Because you're using c_char in your MIDIOUTCAPS structure:

Now I only need to get my MIDIOUTCAPS structure correct.

ValueError: Procedure probably called with too many arguments (60 bytes
in excess)

But I can probably figure that out myself.

thanks!

--

hilsen/regards Max M, Denmark

http://www.mxm.dk/
IT's Mad Science
 
R

Richie Hindle

[Max]
caps = MIDIOUTCAPS()
[...]
print winmm.midiOutGetDevCapsA(deviceID, caps, sizeof(caps))
[...]
ValueError: Procedure probably called with too many arguments (60 bytes
in excess)

You need to pass byref(caps) rather than caps. The API expects a
pointer to the structure, not the structure itself.
 
M

Max M

Richie said:
[Max]
caps = MIDIOUTCAPS()
[...]
print winmm.midiOutGetDevCapsA(deviceID, caps, sizeof(caps))
[...]
ValueError: Procedure probably called with too many arguments (60 bytes
in excess)


You need to pass byref(caps) rather than caps. The API expects a
pointer to the structure, not the structure itself.

Thanks. Yes I figured it out about the same time i read your reply.

I guess it's been about 15 years since I have last coded in c, :-s so
I'm a bit rusty.

--

hilsen/regards Max M, Denmark

http://www.mxm.dk/
IT's Mad Science
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top