ctypes: returning an array from a subroutine

Alex van der Spek zdoor at xs4all.nl
Sun Apr 20 11:36:23 EDT 2014


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 at 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[i] = 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

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

"Alex van der Spek" <zdoor at xs4all.nl> wrote in message 
news:5353bf06$0$2830$e4fe514c at news2.news.xs4all.nl...
>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 at 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 




More information about the Python-list mailing list