How to write Python C++ extensions under Windows

WRITING PYTHON C++ EXTENSIONS IS VERY SIMPLE AND IT WILL HELP YOU UNDERSTAND THE LANGUAGE A LITTLE BETTER.


Writing Python C++ extensions is very simple and it will help you understand the language a little better.


With the purpose in mind of just showing you the mechanics behind building C++ extensions you will create a very basic math library. For this task I will use Visual Studio 2015 Community Edition and Python 2.7.10.


1. Create an empty project. Since this will be a simple math library you will name the project math_demo.



2. Go to Property Pages -> General and set the Target Name, Target Extension and Configuration Type



3. Go to Property Pages -> VC++ Directories and set the include and lib directory



4. Now you are all set up to write down the code. Create a source file.



5. Your first math function will be a random function that will simply invoke C++ rand().


static PyObject* random(PyObject* self, PyObject* args)

{

/* initialize random seed: */

srand(time(NULL));

int random = rand() % 10;

PyObject * python_val = Py_BuildValue("i", random);

return python_val;

}


As you can seePyObjectis not recognized. In order to fix this issue you will have to #include <Python.h>.


You can read more about PyObject here.


Just to summarize:


“All object types are extensions of this type. This is a type which contains the information Python needs to treat a pointer to an object as an object.”


Basically it is like object type from Python.


The random function has to respectPyCFunctiondefinition. You can read about this at the same link from above. But in a few words it has to return PyObject and it has to support two arguments of the type PyObject. The first one in this case is the module and the second one contains all the arguments from the call stack.


6. Now that you have your function you need to export it. The following code snippet will show you how.


PyMODINIT_FUNC initmy_math(void)

{

static PyMethodDef methods[] = {

{ "random", random, METH_NOARGS,

"Generate random number betweeen 0-9" },

{ NULL, NULL, 0, NULL }

};


PyObject *m = Py_InitModule("my_math", methods);

}


So what is going on here?You declare an entry point initname that will be invoked when the module is imported. Basically just as __init__.py works. Using the PyMethodDefstructure you then specify the details about the functions that that you want to export.

As you can see, they are the name, the reference, the way it will be invoked and a description.


As a last step you callPy_InitModule, passing it the module name and the structure that contains the functions information.


7. Now we can build the project and test our code in the python console.




For the second method you’ll make an addition function named add, that adds two integers together.


static PyObject* add(PyObject* self, PyObject* args)

{

int x = 0, y = 0, s = 0;

PyArg_ParseTuple(args, "ii", &x, &y);

s = x + y;

PyObject * python_val = Py_BuildValue("i", s);

return python_val;

}


You have the same function definition, but this time it receives arguments and you have to parse them, add them and return a python specific result.


For details about parsing you can readthis.


Now you only have to add your new method to the module. But this time you have to specify that it will receive arguments.


PyMODINIT_FUNC initmath_demo(void)

{

static PyMethodDef methods[] = {

{ "random", random, METH_NOARGS,

"Generate random number betweeen 0-9" },

{ "add", add, METH_VARARGS, "Add two integers" },

{ NULL, NULL, 0, NULL }

};


PyObject *m = Py_InitModule("math_demo", methods);

}



9. Build and test from Python console.



Building Python extensions in C++ is not that complicated. You can always check their awesome documentation which explains all in depth.


I hope you enjoyed this short tutorial. Stay tuned for more Pythonic learnings!



88 views0 comments

Recent Posts

See All

Yarn

A NEW AND FAST PACKAGE MANAGER There is a new kid on the block, and long story short, he is quite AWESOME. We are talking about YARN, a new package manager that wants to solve a few problems that have

Quick SSH access

HOW TO NOT GET LOST IN THE FOREST OF SSH SERVERS YOU HAVE TO WORK WITH For 8vance, one of the more complex projects that we're working on here in Cluj, we have a growing infrastructure - about 15 serv