I have a bunch of functions that I've written in C and I'd like some code I've written in Python to be able to access those functions.
I've read several questions on here that deal with a similar problem (here and here for example) but I'm confused about which approach I need to take.
One question recommends ctypes and another recommends cython. I've read a bit of the documentation for both, and I'm completely unclear about which one will work better for me.
Basically I've written some python code to do some two dimensional FFTs and I'd like the C code to be able to see that result and then process it through the various C functions I've written. I don't know if it will be easier for me to call the Python from C or vice versa.
To run Python scripts with the python command, you need to open a command-line and type in the word python , or python3 if you have both versions, followed by the path to your script, just like this: $ python3 hello.py Hello World!
The rawest, simplest way is to use the Python C API and write a wrapper for your C library which can be called from Python. This ties your module to CPython. The second way is to use ctypes which is an FFI for Python that allows you to load and call functions in C libraries directly.
Extending Python with C or C++ It is quite easy to add new built-in modules to Python, if you know how to program in C. Such extension modules can do two things that can't be done directly in Python: they can implement new built-in object types, and they can call C library functions and system calls.
You should call C from Python by writing a ctypes wrapper. Cython is for making python-like code run faster, ctypes is for making C functions callable from python. What you need to do is the following:
If I understand well, you have no preference for dialoging as c => python or like python => c. In that case I would recommend Cython
. It is quite open to many kinds of manipulation, specially, in your case, calling a function that has been written in Python from C.
Here is how it works (public api
) :
The following example assumes that you have a Python Class (self
is an instance of it), and that this class has a method (name method
) you want to call on this class and deal with the result (here, a double
) from C. This function, written in a Cython extension
would help you to do this call.
cdef public api double cy_call_func_double(object self, char* method, bint *error): if (hasattr(self, method)): error[0] = 0 return getattr(self, method)(); else: error[0] = 1
On the C side, you'll then be able to perform the call like so :
PyObject *py_obj = .... ... if (py_obj) { int error; double result; result = cy_call_func_double(py_obj, (char*)"initSimulation", &error); cout << "Do something with the result : " << result << endl; }
Where PyObject
is a struct
provided by Python/C API After having caught the py_obj
(by casting a regular python object
, in your cython extension like this : <PyObject *>my_python_object
), you would finally be able to call the initSimulation
method on it and do something with the result. (Here a double
, but Cython can deal easily with vectors
, sets
, ...)
Well, I am aware that what I just wrote can be confusing if you never wrote anything using Cython
, but it aims to be a short demonstration of the numerous things it can do for you in term of merging.
By another hand, this approach can take more time than recoding your Python code into C, depending on the complexity of your algorithms. In my opinion, investing time into learning Cython is pertinent only if you plan to have this kind of needs quite often...
Hope this was at least informative...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With