ctypes: returning an array from a subroutine

A

Alex van der Spek

I have a C code function like this:

++++++++++++++++++++++++++

int __declspec(dllexport) __stdcall bnd2prb(float *in, float *out, int init)
{enum {OK, Error, Not_Valid};
...
return(OK):
}

++++++++++++++++++++++++++

And in Python I am trying to call this C function:

++++++++++++++++++++++++++

import ctypes
import struct
import array

_snns =
ctypes.windll.LoadLibrary(r'C:\MSDEV\Projects\Cyctrac\Debug\Cyctrac.dll')

_cosm = getattr(_snns, '_bnd2prb@12')

_cosm.argtypes = (ctypes.POINTER(ctypes.c_float),
ctypes.POINTER(ctypes.c_float),
ctypes.c_long)

_cosm.restype = ctypes.c_float

def snns(indata, outdat):
"""Calls the neural net, returns a vector of 4.

"""
global _cosm

init = ctypes.c_long(0)

ilen = len(indata)
olen = len(outdat)

itype = ctypes.c_float * ilen
otype = ctypes.c_float * olen

iok = _cosm(itype(*indata), ctypes.pointer(otype(*outdat)), init)

if not iok:
return True
else:
return False

indata = [0.5 for x in range(31)]
outdat = [0.0 for x in range(4)]

indata[1]=3.14

ok = snns(indata, outdat)

if ok:
print indata
print outdat

+++++++++++++++++++++++++++++++

This executes but leaves the outdat array unchanged.

Obviously I haven't understood ctypes well enough.

Returning arrays from FORTRAN I routinely do through a string_buffer.

That works very well but did not work here at all.

Any and all help welcome.

Alex van der Spek
 
A

Alex van der Spek

Many hours later I found a working solutions in ctypes:

The below makes sense to me but I am still at a loss why the first solution
did not work.

Anybody willing to explain for my better understanding?

Regards,
Alex van der Spek

++++++++++++++++++++++++++++++++++++++++++++

_snns =
ctypes.windll.LoadLibrary(r'C:\MSDEV\Projects\Cyctrac\Debug\Cyctrac.dll')

_cosm = getattr(_snns, '_bnd2prb@12')

_cosm.restype = ctypes.c_int

def snns(indata, outdat):
"""Calls the neural net, returns a vector of 4.

"""
global _cosm

init = ctypes.c_long(0)

odat = (ctypes.c_float * len(outdat))(*outdat)
idat = (ctypes.c_float * len(indata))(*indata)

iok = _cosm(ctypes.byref(idat), ctypes.byref(odat), init)

for i, x in enumerate(odat):
outdat = x

if not iok:
return odat
else:
return False

indata = [0.5 for x in range(31)]
outdat = [0.0 for x in range(4)]

ok = snns(indata, outdat)

if ok:
print indata
print outdat

+++++++++++++++++++++++++++++++++++++++
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top