Python can be mixed with other languages (especially C) by:
Complete docs on python.org
Programs can use libpython to run the Python interpreter
Trivial example (embed0.c):
#include <Python.h> main(int argc,char **argv) { Py_Initialize(); PyRun_SimpleString("import time\n" "print 'time =', time.time()\n"); Py_Finalize(); }
Compile with the command:
cc -Xlinker -export-dynamic -I/usr/include/python embed0.c -o embed0 -L/usr/lib/python/config/ -lpython2.2 -ldl -lpthread -lutil -lm
The flags and libraries that a program needs to be linked with can be found using the script Linking.py
One can also run the interpreter on files
Highlights of embed1.c:
Py_Initialize(); fp = fopen(filename, "r"); PyRun_SimpleFile(fp, filename); fclose(fp); Py_Finalize();
Functions to use:
Other functions exist for more advanced access to Python features (e.g. creating Python objects)
pycave.c uses embedded Python to allow one to run a Python script in a CAVElib program
pycave calls 2 functions defined in the Python script:
C functions can be called from Python by extending Python
This involves defining a new module, that can be imported
The module has a table of function names and corresponding C functions to call for each
A function must parse Python objects that are the function arguments, and return a Python object
Example extension functions:
static PyObject* encrypt(PyObject *self, PyObject *args) { char *string, *returnstring, *p; if (!PyArg_ParseTuple(args, "s", &string)) return NULL; returnstring = strdup(string); for (p=returnstring; *p; p++) *p = rot13(*p); return Py_BuildValue("s", returnstring); }
static PyObject* helloworld(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) /* No arguments expected */ return NULL; printf("Hello, world!\n"); Py_INCREF(Py_None); return Py_None; /* No return value */ }
A module is created with the new functions via:
static PyMethodDef newMethods[] = { {"encrypt", encrypt, METH_VARARGS, "Returns an encrypted version of a string."}, {"helloworld", helloworld, METH_VARARGS, "Prints 'Hello, world!'."}, {NULL, NULL, 0, NULL} }; Py_InitModule("mymodule", newMethods);
Python code that is subsequently executed via an embedded interpreter (PyRun_*) can then do:
import mymodule cryptText = mymodule.encrypt('A secret message') mymodule.helloworld()
pycave2.c uses embedded Python along with extension functions
It creates a module cave, with the functions:
To make a module loadable from regular (non-embedded) Python, you
must build a shared library
(sometimes called a 'DSO' in Unix, or 'DLL' in Windows)
The code must include an init function, which is called when the module is loaded
If the module is named foo, then the init function is
initfoo()
For example:
void initcrypto(void) { (void) Py_InitModule("crypto", newMethods); }
In Unix, compile a DSO like this:
cc -I/usr/include/python -O -shared -o crypto.so crypto.c
The location of the module may need to be added to your PYTHONPATH environment variable; e.g.:
setenv PYTHONPATH ~/python
Another way to extend Python is via the ctypes module
With ctypes, one can access a system library and get pointers to functions within it
These functions are normally only callable from languages like C
ctypes creates Python function objects to wrap them
It also converts between Python & C data types for arguments and return values
Example:
import ctypes libgl = ctypes.cdll.LoadLibrary('/usr/lib/libGL.so') glMultiTexCoord2dARB = libgl.glMultiTexCoord2dARB glMultiTexCoord2dARB.argtypes = [ ctypes.c_uint , ctypes.c_double , ctypes.c_double ] glGetError = libgl.glGetError glGetError.argtypes = [ ] glGetError.restype = ctypes.c_uint