Tuesday, 6 May 2014

Interfacing Python with C/C++ (Passing Python List into C function)

The following illustrates an example on how to pass a Python list as argument into a C/C++ function and subsequently update the elements in it. It assumes that the list contains floating numbers. The example is based on Python/C API Reference Manual version 2.7.6

Compile the following file example.cpp into a dynamic link library. Here, I have used NetBeans 8.0 running on Ubuntu 14.04 to create a C++ dynamic link library project. The output is a file example.so.
//file: example.cpp

#include <Python.h>

extern "C" {
  PyObject* doo(PyObject* arg) {
  //get the number of elements in Python list
  long cnt = PyList_Size(arg);
  std::cout<<"Number of items: "<<cnt<<std::endl;

  for (long i=0; i<cnt; i++) {
    //print element value
    std::cout<<PyFloat_AsDouble(PyList_GET_ITEM(arg,i))<<std::endl;

    //change element in Python list
    PyList_SetItem(arg,i,PyFloat_FromDouble(i));
    std::cout<<PyFloat_AsDouble(PyList_GET_ITEM(arg,i))<<std::endl;
  }
  //return None
  return Py_None;
}

The following Python code loads the library and call the function doo. Do ensure the Python interpreter is version 2.7.6.
import ctypes

#load example.so (update path to library file accordingly)
dll = ctypes.CDLL('example.so')
#set the return data type of function doo to Python object
dll.doo.restype = ctypes.py_object
#set the argument data type of function doo to Python object,
#one element per argument in a list
dll.doo.argtypes = [ctypes.py_object]
l=[1.11 2.22 3.33]
print dll.doo(l)

The following is the output of the Python code.
Number of items: 3
1.11
0
2.22
1
3.33
2
None

To verify that the list has indeed been modified, print the list in python console.
>>> l
[0.0, 1.0, 2.0]

No comments:

Post a Comment