Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #112290

RE: Issue with ctypes and callback functions

From Bill Somerville <BSomerville@flexerasoftware.com>
Newsgroups comp.lang.python
Subject RE: Issue with ctypes and callback functions
Date 2016-08-03 13:21 +0000
Message-ID <mailman.144.1470231341.6033.python-list@python.org> (permalink)
References <0E5668E32633FB4FBBA1709825C0EDFDD24AAE@SCHEXMB2.acresso.com> <CACL+1aufZSd6kcDP9FSEx4zeZ2zBCnM7jucRprGiDSxddB0GSQ@mail.gmail.com> <0E5668E32633FB4FBBA1709825C0EDFDD24B77@SCHEXMB2.acresso.com>

Show all headers | View raw


-----Original Message-----
From: eryk sun [mailto:eryksun@gmail.com] 
Sent: 03 August 2016 13:16
To: python-list@python.org
Cc: Bill Somerville <BSomerville@flexerasoftware.com>
Subject: Re: Issue with ctypes and callback functions

On Wed, Aug 3, 2016 at 9:38 AM, Bill Somerville <BSomerville@flexerasoftware.com> wrote:
>
> Is this a good place to ask questions about the above?

Discussing ctypes is fine here. There's also a ctypes-users list.


Thanks Eryk,

I am trying to handle Python callback functions in a SWIG interface, SWIG does not support callbacks where the target is a Python callable but I can do this with ctypes. My problem is that I need to have the callback receive a SWIG wrapped type as an argument by reference. I see that if I use a ctypes.Structure type then it works nicely but I have a huge and changing API to wrap and do not want to manually describe every C struct with ctypes.Structure when SWIG has already automatically created its own shadow classes. The SWIG struct wrapper is just a class wrapping a pointer so can be easily be passed just like ctypes.Structure can be. How do I tell ctypes that it needs to reconstitute the type from an address in the callback thunk it generates?

I have tried defining from_param() and self._as_parameter_ for the types which works for passing to a function but I don't need that as SWIG does that already. With callback arguments I get various errors depending on what methods/attributes I supply like:

Parsing argument 0
TypeError: cannot build parameter

At the point where the callback is being called.

To summarize:
++++++++++++++++++++++++++++++++++++
C API like:

typedef struct {
    int member;
    /* ... */
} my_type;
typedef int (*pfn) (my_type const *);
int fn (pfn);

Implementation could be:

#include "api.h"
int fn (pfn cb) {
    my_type t = {42, /* ... */};
    return cb (&t);
}

I want Python code like:

from ctypes import *
import api  # SWIG extension module

def my_cb (t):
    print ('in callback with:', t.member)
    return 0

proto = CFUNCTYPE (c_int, my_type)
cb = proto (my_cb)
res = api.fn (cast (cb, c_void_p).value)
print ('fn returned:', res)

------------------------------------------------

I can extend the SWIG shadow class to do the creation of the prototype and thunk, the required cast above and any extra attributes or methods like _as_parameter_ and from_param() but I can't see any way of having the Python callback (my_cb) magically receive the SWIG wrapped 'my_type' struct.

TIA
Bill.

Back to comp.lang.python | Previous | Next | Find similar | Unroll thread


Thread

RE: Issue with ctypes and callback functions Bill Somerville <BSomerville@flexerasoftware.com> - 2016-08-03 13:21 +0000

csiph-web