Python establishes tightly bound wrappers with C ,so that it can extend the C APIs,and also get into closer relation with the system interface.Writing wrappers in python is achieved by using PyObjects in the C code its easy to distinguish the python code in the C file as most of the python objects and APIs start with Py or PY.
In the process of writing a python wrapper for a C function the following steps emerge
#myadd.c
Expand|Select|Wrap|Line Numbers
- int add(int a, int b)
- {
- return a+b;
- }
#wrapping.c
#include<python2.4/Python.h>
The first step would be to include a Python header ,which includes a few of the necessary commands like stdio.h,string.h...
The second step would be to convert function arguments from Python to C,and to return results in a Python-friendly form.
Expand|Select|Wrap|Line Numbers
- PyObject *wrap_add(PyObject *self, PyObject *args) {
- int a,b,result;
- if (!PyArg_ParseTuple(args,"ii",&a,&b))
- return NULL;
- result = add(a,b);
- return Py_BuildValue("i",result);
- }
The conversion of data between Python and C is performed using two functions :
int PyArg_ParseTuple(PyObject *args, char *format, ...)
PyObject *Py_BuildValue(char *format, ...)
The PyArg_ParseTuple is a python API which checks for the types of the argument that are passed,stored in the memory if they are right and return a null when wrong.The Py_BuildValue returns the result in a python form from the C function.
In our case add takes two arguments which is passed to the PyArg_ParseTuple then the C function add is called and the value is stored in a integer result,which is retrived using the Py_BuildValue
The last step would be to make the interpreter understand that we have implemented a wrapper.We intialise it using the function
Expand|Select|Wrap|Line Numbers
- static PyMethodDef exampleMethods[] = {
- { "add", wrap_add, METH_VARARGS,"A simple addition program" },
- { NULL, NULL, 0, NULL }
- };
- void initmyadd() {
- PyObject *m;
- m = Py_InitModule("myadd", exampleMethods);
- }
When myadd is called for the first time It calls initmyadd,which creates a module object (which is inserted in the dictionary sys.modules under the key "myadd"),and inserts built-in function objects into the newly created module based upon the table (an array of PyMethodDef structures) that was passed as its second argument. Py_InitModule() returns null when intializations go wrong.PyMODINIT_FUNC API is used for void return type function declarations.