9.5.2 : The C++ module file
Now, let's write the barycentrepython.cpp file :
First, we have to activate the numpy we disabled in the previous files. Otherwise, you will get a segmentation fault out of knowhere.
1 2 3 4 |
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #ifndef DISABLE_COOL_ARRAY #define PY_ARRAY_UNIQUE_SYMBOL core_ARRAY_API #endif |
Then, we include all the previous wrapper and the python stuff, of course.
1 2 3 4 5 6 7 |
#include <iostream> #include <Python.h> #include "structmember.h" #include <numpy/arrayobject.h> #include "barycentreWrapper.h" |
It is always good to have a documentation of your function. The folowing will appear when you call a function with '?' or shift-tab in jupyter-notebook :
1 2 3 4 5 6 7 |
std::string barycentreWrapper_docstring = "Compute a 2d barycentre with aligned table of float32\n\ Parameters :\n\ tabX : table of value (float32 aligned)\n\ tabY : table of value (float32 aligned)\n\ tabA : table of value (float32 aligned)\n\ Return :\n\ barycentre (x, y)"; |
We define the callable method of our wrapper :
1 2 3 4 5 |
static PyMethodDef _barycentre_methods[] = { {"barycentre", (PyCFunction)barycentreWrapper, METH_VARARGS, barycentreWrapper_docstring.c_str()}, {NULL, NULL} }; |
Notice that you can expose the functions you want, not all the functions you developed.
Now, we have to define the python module itself :
1 2 3 4 5 6 7 8 9 10 11 |
static PyModuleDef _barycentre_module = { PyModuleDef_HEAD_INIT, "barycentrepython", "", -1, _barycentre_methods, NULL, NULL, NULL, NULL }; |
Now we define the function which will be called on the import of our module.
Notice you must call this function PyInit_NameOfYouModule where NameOfYouModule is the name of THIS file.
We create the module, which is a PyObject.
Do not forget to call import_array otherwise you will get a warning on the best cases and a segmentation fault on your module import.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
///Create the python module barycentre /** @return python module barycentre */ PyMODINIT_FUNC PyInit_barycentrepython(void){ PyObject *m; import_array(); m = PyModule_Create(&_barycentre_module); if(m == NULL){ return NULL; } return m; } |
The full barycentrepython.cpp file :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
/*************************************** Auteur : Pierre Aubert Mail : pierre.aubert@lapp.in2p3.fr Licence : CeCILL-C ****************************************/ #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #ifndef DISABLE_COOL_ARRAY #define PY_ARRAY_UNIQUE_SYMBOL core_ARRAY_API #endif #include <iostream> #include <Python.h> #include "structmember.h" #include <numpy/arrayobject.h> #include "barycentreWrapper.h" std::string barycentreWrapper_docstring = "Compute a 2d barycentre with aligned table of float32\n\ Parameters :\n\ tabX : table of value (float32 aligned)\n\ tabY : table of value (float32 aligned)\n\ tabA : table of value (float32 aligned)\n\ Return :\n\ barycentre (x, y)"; static PyMethodDef _barycentre_methods[] = { {"barycentre", (PyCFunction)barycentreWrapper, METH_VARARGS, barycentreWrapper_docstring.c_str()}, {NULL, NULL} }; static PyModuleDef _barycentre_module = { PyModuleDef_HEAD_INIT, "barycentrepython", "", -1, _barycentre_methods, NULL, NULL, NULL, NULL }; ///Create the python module barycentre /** @return python module barycentre */ PyMODINIT_FUNC PyInit_barycentrepython(void){ PyObject *m; import_array(); m = PyModule_Create(&_barycentre_module); if(m == NULL){ return NULL; } return m; } |
You can download it here.