ctypes, function pointers and a lot of trouble

Nick Craig-Wood nick at craig-wood.com
Fri May 30 07:30:20 EDT 2008


Matt <mr.edel at gmx.at> wrote:
>  Okay, thanks a lot for your reply Nick, I think you pushed me back on 
>  the right way.

Good!

>  Now I started with trying to implement the callback functions and am 
>  stuck at the following point:
> 
>  I define my classes/structures/unions:
> 
>  class cdStream(Structure):
>       _fields_ = [("contextH", c_uint),
>                        ("open", c_void_p),
[snip]
>  then i define my functions (right now I do just nothing) and at the same 
>  time I define the datatypes like they're listed in my C sample program:
> 
>  def pystreamopen (contextH, mode, pErr):
>       pass
> 
>  cstreamopen = CFUNCTYPE(c_uint, c_ushort, c_uint)
[snip]
>  and now the problem starts: i want the pointers in the cdStream 
>  Structure point at my functions and tried to do it the following way:
> 
>  data = cdStgMedium()
>  data.type = 0
>  data.u.pStream.contextH = c_uint(3) #must be some kind of identifier.
>  data.u.pStream.open = cstreamopen(pystreamopen)
[snip]
>  unfortunately that doesn't work because Python returns a TypeError: 
>  incompatible types, CFunctionType instance instead of c_void_p instance
> 
>  Any ideas/help (please)?

Probably the best thing is if you define the union with the types of
the pointers to your functions instead of c_void_p, eg

  class cdStream(Structure):
       _fields_ = [("contextH", c_uint),
                        ("open", cstreamopen),
                        ("close", cstreamclose), # etc...

This will involve you re-ordering your definitions.

Or alternatively, you could cast the function pointer to a c_void_p
first, eg

  data.u.pStream.open = c_void_p( cstreamopen(pystreamopen) )

which should work but is less typesafe.

-- 
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick



More information about the Python-list mailing list