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
