Python Programming/Extending with C

      This gives a minimal Example on how to Extend Python with C. Linux is used for building (feel free to extend it for other Platforms). If you have any problems, please report them (e.g. on the dicussion page), I will check back in a while and try to sort them out.

      Using the Python/C API

      On an Ubuntu system, you might need to run

      $ sudo apt-get install python-dev           // this command ensures that you can use the line #include <Python.h>
      

      A minimal example

      The minimal example we will create now is very similar in behaviour to the following python snippet:

       def say_hello(name):
           "Greet somebody."
           print "Hello %s!" % name
      

      The C source code (hellomodule.c)

      #include <Python.h>
       
      static PyObject* say_hello(PyObject* self, PyObject* args)
      {
          const char* name;
       
          if (!PyArg_ParseTuple(args, "s", &name))
              return NULL;
       
          printf("Hello %s!\n", name);
       
          Py_RETURN_NONE;
      }
       
      static PyMethodDef HelloMethods[] =
      {
           {"say_hello", say_hello, METH_VARARGS, "Greet somebody."},
           {NULL, NULL, 0, NULL}
      };
       
      PyMODINIT_FUNC
       
      inithello(void)
      {
           (void) Py_InitModule("hello", HelloMethods);
      }
      

      Building the extension module with GCC for Linux

      To build our extension module we create the file setup.py like:

      from distutils.core import setup, Extension
       
      module1 = Extension('hello', sources = ['hellomodule.c'])
       
      setup (name = 'PackageName',
              version = '1.0',
              description = 'This is a demo package',
              ext_modules = [module1])
      

      Now we can build our module with

      python setup.py build
      

      The module hello.so will end up in build/lib.linux-i686-x.y.

      Building the extension module with GCC for Microsoft Windows

      Microsoft Windows users can use MinGW to compile this from cmd.exe using a similar method to Linux user, as shown above. Assuming gcc is in the PATH environment variable, type:

      python setup.py build -cmingw32
      

      The module hello.pyd will end up in build\lib.win32-x.y, which is a Python Dynamic Module (similar to a DLL).

      An alternate way of building the module in Windows is to build a DLL. (This method does not need an extension module file). From cmd.exe, type:

      gcc -c  hellomodule.c -I/PythonXY/include
      gcc -shared hellomodule.o -L/PythonXY/libs -lpythonXY -o hello.dll
      

      where XY represents the version of Python, such as "24" for version 2.4.

      Building the extension module using Microsoft Visual C++

      With VC8 distutils is broken. We will use cl.exe from a command prompt instead:

      cl /LD hellomodule.c /Ic:\Python24\include c:\Python24\libs\python24.lib /link/out:hello.dll
      

      Using the extension module

      Change to the subdirectory where the file `hello.so` resides. In an interactive python session you can use the module as follows.

      >>> import hello
      >>> hello.say_hello("World")
      Hello World!
      

      A module for calculating fibonacci numbers

      The C source code (fibmodule.c)

      #include <Python.h>
       
      int _fib(int n)
      {
          if (n < 2)
              return n;
          else
              return _fib(n-1) + _fib(n-2);
      }
       
      static PyObject* fib(PyObject* self, PyObject* args)
      {
          int n;
       
          if (!PyArg_ParseTuple(args, "i", &n))
              return NULL;
       
          return Py_BuildValue("i", _fib(n));
      }
       
      static PyMethodDef FibMethods[] = {
          {"fib", fib, METH_VARARGS, "Calculate the Fibonacci numbers."},
          {NULL, NULL, 0, NULL}
      };
       
      PyMODINIT_FUNC
      initfib(void)
      {
          (void) Py_InitModule("fib", FibMethods);
      }
      

      The build script (setup.py)

      from distutils.core import setup, Extension
       
      module1 = Extension('fib', sources = ['fibmodule.c'])
       
      setup (name = 'PackageName',
              version = '1.0',
              description = 'This is a demo package',
              ext_modules = [module1])
      

      How to use it?

      >>> import fib
      >>> fib.fib(10)
      55
      
      ↑Jump back a section

      Using SWIG

      Creating the previous example using SWIG is much more straight forward. To follow this path you need to get SWIG up and running first. To install it on an Ubuntu system, you might need to run the following commands

      $ sudo apt-get install libboost-python-dev 
      $ sudo apt-get install python-dev
      

      After that create two files.

      /*hellomodule.c*/
       
      #include <stdio.h>
       
      void say_hello(const char* name) {
          printf("Hello %s!\n", name);
      }
      
      /*hello.i*/
       
      %module hello
      extern void say_hello(const char* name);
      

      Now comes the more difficult part, gluing it all together.

      First we need to let SWIG do its work.

      swig -python hello.i
      

      This gives us the files `hello.py` and `hello_wrap.c`.

      The next step is compiling (substitute /usr/include/python2.4/ with the correct path for your setup!).

      gcc -fpic -c hellomodule.c hello_wrap.c -I/usr/include/python2.4/
      

      Now linking and we are done!

      gcc -shared hellomodule.o hello_wrap.o -o _hello.so
      

      The module is used in the following way.

      >>> import hello
      >>> hello.say_hello("World")
      Hello World!
      
      ↑Jump back a section
      Last modified on 10 July 2012, at 11:23