ctypes, function pointers and a lot of trouble

Matt mr.edel at gmx.at
Tue Jun 3 12:22:58 CEST 2008


ouch, I should have seen that c_char... :S Well, I guess I just prove 
that it's useless to go to work and do some programming while having a 
headache like I had yesterday...

okay well, back to topic:

The DLL function seems to accept my parameters now, but unfortunately 
Python terminates after the DLL gets the result from the "open" callback 
function (at least its printouts are the last I get before it 
terminates). So without any kind of error message it's getting more 
difficult now.

Well, since I didn't invest much time into my callback functions I 
suspect the error must be somewhere in there.

This is my code:


class MemStreamData(Structure):
     _fields_ = [("mode", c_byte),
                      ("lPos", c_uint),
                      ("dwVisibleSize", c_uint),
                      ("dwBufferSize", c_uint),
                      ("cpBuffer", POINTER(c_char))]

class FilStreamData (Structure):
     _fields_ = [("szFileName", c_char * 30),
                      ("hFile", c_uint)]

def pystreamopen (contextH, mode, pErr=0):
     print "opening..."
     print contextH
     print mode
     print pErr
     return 0

cstreamopen = CFUNCTYPE(c_uint, c_ushort, c_uint)

def pystreamclose (contextH, pErr):
     print "closing..."
     return 0

cstreamclose = CFUNCTYPE(c_uint, c_uint)

def pystreamread (contextH, pBuf, pBufsize, pErr):
     print "reading..."
     return 0

cstreamread = CFUNCTYPE(c_uint, c_void_p, c_uint, c_uint)

def pystreamtell (contextH, pErr):
     print "telling..."
     return 0

cstreamtell = CFUNCTYPE(c_uint, c_uint)

def pystreamseek (contextH, origin, offset, pErr):
     print "seeking..."
     return 0

cstreamseek = CFUNCTYPE(c_uint, c_uint, c_uint, c_uint)

def pystreamwrite (contextH, origin, offset, pErr):
     print "writing..."
     return 0

cstreamwrite = CFUNCTYPE(c_uint, c_void_p, c_uint, c_uint)

class cdStream(Structure):
     _fields_ = [("contextH", POINTER(MemStreamData)),
                      ("open", cstreamopen),
                      ("close", cstreamclose),
                      ("read", cstreamread),
                      ("write", cstreamwrite),
                      ("seek", cstreamseek),
                      ("tell", cstreamtell)]


This is the way I create the vars:


     databuf = create_string_buffer(100000)
     cbuffer.mode = c_byte(0)
     cbuffer.lPos = c_uint(0)
     cbuffer.dwVisibleSize = 100000
     cbuffer.dwBufferSize = 100000
     cbuffer.cpBuffer = databuf

     stream = cdStream()
     stream.contextH = POINTER(MemStreamData)(cbuffer)
     stream.open = cstreamopen(pystreamopen)
     stream.close = cstreamclose(pystreamclose)
     stream.write = cstreamwrite(pystreamwrite)
     stream.tell = cstreamtell(pystreamtell)
     stream.read = cstreamread(pystreamread)

     data = cdStgMedium()
     data.Type = c_uint(1) # 0...FilStream 1...MemStream
     data.u.pStream = POINTER(cdStream)(stream)

     errorcode = cdsdk.CDGetReleasedData(devicehandle, byref(cbfunct), 
c_uint(0), c_uint(0), byref(datainfo), POINTER(cdStgMedium)(data))


Now I have two problems:

1st: since contextH is not a c_uint (and pErr is a pointer) as I thought 
earlier, I tried to change my definition of the open function to:

cstreamopen = CFUNCTYPE(POINTER(MemStreamData), c_ushort, POINTER(c_uint))

unfortunately that throws an error when I try to:

stream.open = cstreamopen(pystreamopen)

2nd: as may saw, I defined "def pystreamopen (contextH, mode, pErr=0)". 
The pErr variable should be a pointer to a c_uint where my function can 
tell the DLL that opening the stream went well (or give some errorcode).

When I do not define pErr=0 and simply say pErr, I get the following error:

Traceback (most recent call last):
  File "\loewis\25\python\Modules\_ctypes\callbacks.c", line 206, in 
'calling callback function'
TypeError: pystreamopen() takes exactly 3 arguments (2 given)

At first I thought okay, maybe there's no pErr and there's some error in 
the C-Code, but when I do "def pystreamopen (contextH, mode)" I get the 
same Error with:
TypeError: pystreamopen() takes exactly 3 arguments (2 given)

Any ideas?

And another question: my callback functions are all defined as void... 
in C. That means that there shouldn't be anything returned. I tried this 
by using the pass statement, but got an error that returntype int was 
expected. Also "return" or "return None" don't work. Why?

Puh, long mail again... hope you're so kind again and take the time to 
help me out.

Best regards from Austria,

More information about the Python-list mailing list