return a ctypes object to C
Arnaud Loonstra
arnaud at sphaero.org
Thu Oct 31 09:13:57 EDT 2019
On 30-10-2019 09:32, Arnaud Loonstra wrote:
> Hi all,
>
> I'm trying to wrap my head around the ctypes API. I have a C structure I
> wish to create in Python and then return from python to C.
>
> So a python method is called from C and needs to return an object which
> we then process in C again.
>
> I have a binding to access and create the C methods and structures so in
> Python I can call the Zmsg() constructor. I now need to return this.
>
> My python test method is simply:
>
> def actor_test( *args, **kwargs):
> print("test")
> msg = Zmsg()
> frame = Zframe(b"Hello", 5)
> msg.prepend(frame)
> return msg
>
> the method is called from C as follows:
>
> PyObject *pReturn = PyObject_CallObject(pFunc, NULL);
>
> This correctly calls the method. However the returned object is of
> course a PyObject*. The debugger says it's
>
> "<czmq._czmq_ctypes.Zmsg object at 0x7ffff5f18e50>" PyObject
> [class] "<class 'czmq._czmq_ctypes.Zmsg'>"
> [super class] "<class 'object'>"
> [meta type] "<class 'type'>"
> ob_refcnt 1 Py_ssize_t
>
> However how I can I get it back to the original C type (zmsg_t *)
>
> Any help really appreciated.
>
What I've found so far is that I can return the address of the ctypes
object.
msg = Zmsg()
frame = Zframe(b"Hello", 5)
msg.prepend(frame)
return addressof(msg._as_parameter_.contents)
In C I can then cast it back to the original type.
PyObject *pReturn = PyObject_CallObject(pFunc, NULL);
assert(pReturn);
long bla = PyLong_AsLong(pReturn);
zmsg_t* test = (zmsg_t *)bla;
assert(test);
char *hello = zmsg_popstr(test);
assert(hello);
assert(streq(hello, "Hello"));
This works, I'm not sure if this is the right way. It also creates a
complicated setup with the garbage collector.
Anybody better ideas?
Rg,
Arnaud
More information about the Python-list
mailing list