I'd like to convert some ctypes code to use cython instead, but I'm struggling. Essentially, the ctypes code:
- copies the contents (floats) of two lists into C-compatible structs
- sends the structs to my binary via FFI
- receives the structs back (the length is never modified)
- copies the contents to two new lists
- sends the structs back across the FFI boundary so their memory can be freed
My ctypes code looks like this so far:
rlib.h
#ifndef RLIB_H
#define RLIB_Htypedef struct _FFIArray {void* data;size_t len;
} _FFIArray;typedef struct _Result_Tuple {_FFIArray e;_FFIArray n;
} _Result_Tuple;_Result_Tuple convert_to_bng_threaded(_FFIArray x, _FFIArray y);
void drop_float_array(_FFIArray x, _FFIArray y)#endif
mylib.pxd
cdef extern from "rlib.h":struct _FFIArray:void* datasize_t lenstruct _Result_Tuple:_FFIArray e_FFIArray ncdef _Result_Tuple convert_to_bng_threaded(_FFIArray x, _FFIArray y)cdef void drop_float_array(_FFIArray x, _FFIArray y)
util_cython.pyx
import cython
from mylib cimport _FFIArray, convert_to_bng_threaded, drop_float_arraydef call_convert_bng(_FFIArray x, _FFIArray y):return convert_to_bng_threaded(x, y)def call_drop_float_array(_FFIArray x, _FFIArray y):return drop_float_array(x, y)
setup.py
from setuptools import setup, Extension, find_packagesfrom Cython.Build import cythonize
from Cython.Distutils import build_extext = Extension('util_cython', sources=['util_cython.pyx'],libraries=['latlon_bng',],library_dirs=['.',],include_dirs=['.']
)extensions = [ext,]setup(name = "util_cython",ext_modules = cythonize(extensions),cmdclass={'build_ext': build_ext},
)
I have a few questions about how to proceed:
Firstly, the compilation step is currently failing:
python setup.py build_ext --inplace
Compiling util_cython.pyx because it changed.
[1/1] Cythonizing util_cython.pyxError compiling Cython file:
------------------------------------------------------------
...
import cython
from mylib cimport _FFIArray, convert_to_bng_threaded, drop_float_arraydef call_convert_bng(_FFIArray x, _FFIArray y):return convert_to_bng_threaded(x, y)^
------------------------------------------------------------util_cython.pyx:5:34: Cannot convert '_Result_Tuple' to Python object
Traceback (most recent call last):File "setup.py", line 17, in <module>ext_modules = cythonize(extensions),File "/Users/sth/dev/cythonize_test/venv/lib/python2.7/site-packages/Cython/Build/Dependencies.py", line 912, in cythonizecythonize_one(*args)File "/Users/sth/dev/cythonize_test/venv/lib/python2.7/site-packages/Cython/Build/Dependencies.py", line 1034, in cythonize_oneraise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: util_cython.pyx
Why is Cython failing to convert _Result_tuple
?
Secondly, how do I define a cython function to accept lists (or arrays; anything that supports __iter__
), and copy their contents into _FFIArray
structs, so I can call call_convert_bng
?