We continue the topic of how to call C / C ++ from Python3 . Now we use the C API to create the module, in this example we can figure out how cffi and other libraries simplify our lives. Because in my opinion this is the most difficult way.
C
A test library to demonstrate working with global variables, structures, and functions with arguments of various types. In my articles I use variations of the same library, depending on the method that I now use. Links to previous methods below.
test.h
typedef struct test_st_s test_st_t; extern int a; extern double b; extern char c; static PyObject *func_hello(PyObject *self, PyObject *args); static PyObject *func_ret_int(PyObject *self, PyObject *args); static PyObject *func_ret_double(PyObject *self, PyObject *args); static PyObject *func_ret_str(PyObject *self, PyObject *args); static PyObject *func_many_args(PyObject *self, PyObject *args); static PyObject *func_ret_struct(PyObject *self, PyObject *args); struct test_st_s { PyObject_HEAD
test.c
The module is required to indicate that it will include: functions, global variables and structures. Each such thing needs to be described, the most difficult for its data types (structure ...). Approximately such a file is generated by cffi .
To work, you must connect the header files:
#include <Python.h> #include <structmember.h> //
Compilation flags:
$(python3-config --includes --ldflags) -fPIC
The following function is responsible for processing the arguments:
PyArg_ParseTuple(args, "ids", &val1, &val2, &val3);
The first is an argument of type int, it has the letter designation i
2nd float / double - d
3rd string - s
All possible letter designations of data types can be found here.
Now we turn to the description of how to describe the structure.
struct.c:
And that’s all for:
struct test_st_s { PyObject_HEAD
Agree, not a little. Moreover, methods can be defined for the structure (as an example, test_st_print ).
In the code I try to make more comments, which would be less to describe separately.
Python
An example of working with a C module from Python :
import sys import time
The module has become native.
Pros and Cons of the C API
Pros :
Cons :
- difficult to describe your data types in C API
- It’s difficult for pure programmers to implement it for Python , and not for them either ... (for me, the simplest is through ctypes )
- module (library) will be only for Python
The average test execution time on each method with 1000 starts:
- ctypes: - 0.0004987692832946777 seconds ---
- CFFI: - 0.00038521790504455566 seconds ---
- pybind: - 0.0004547207355499268 seconds ---
- C API: - 0.0003561973571777344 seconds ---
References