I found here and here that one can use Cython to convert Python to C, but I cannot find any step-by-step example. Let's say I have a simple function:
foo.pyx
cdef void foo(double* x):
x[0] = 0.0
setup.py
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("foo.pyx")
)
then I run: python setup.py build_ext --inplace to get foo.c and foo.so files (and build directory). Well, I would like to use translated (I hope) foo function in main.c. What should I put into main.c file and how to compile it in order to be able to use foo function? I am using gcc.
Far from a c expert but for me using ubuntu, the following works:
main.c:
foo.pyx:
From the same directory:
Then:
Then just run.
I used
pkg-config --cflags python
to get the flags:Without calling Py_Initialize (Initialize the Python interpreter. In an application embedding Python, this should be called before using any other Python/C API functions;), you will get:
Without
initfoo()
orimport_foo()
you get a:If you don't call Py_Finalize:
Py_Initialize
a no-op when called for a second time (without calling Py_Finalize() first).To get the delorean example from the docs to run:
main.py:
delorean.pyx:
The procedure is the same, the only change was I had to use
ctypedef
with the Vehicle struct or else in main or use I had t usestruct Vehicle car;
in main:You can also get it to work without using
Py_Initialize
etc...In
foo.pyx
you just need to make the function public:I added
#include <python2.7/Python.h>
just importedfoo.h
in main.c and removedPy_Initialize();
etc. Just importingpython.h
would not work for me but that may not be the case for everyone.Compiling was the same:
If you are using the api version then just include the api header or vice versa as per the docs However, note that you should include either modulename.h or modulename_api.h in a given C file, not both, otherwise you may get conflicting dual definitions.
To do the same with the delorean example I had to use
libc.stdio
to print the strings to avoid a segmentation fault:main:
It might make more sense to return the values:
main: