Download Full size - Computer Science - University of San Francisco

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Programming Language Paradigms
Extending Python with C
Chris Brooks
Department of Computer Science
University of San Francisco
Department of Computer Science — University of San Francisco – p.1/??
17-0:
Using C code from Python
Sometimes, you might want to call C/C++ code from
Python.
What are some examples?
Department of Computer Science — University of San Francisco – p.2/??
17-1:
Using C code from Python
Sometimes, you might want to call C/C++ code from
Python.
Optimize performance
Interface with a third-party package
Integrate legacy code into a new application.
Department of Computer Science — University of San Francisco – p.3/??
17-2:
Using C code from Python
There are two approaches to combining C ond Python
Write wrapper code by hand.
Use an automatic wrapper generator
We’ll take a brief look at each.
Department of Computer Science — University of San Francisco – p.4/??
17-3:
Hello World
Let’s start with Hello World.
No inputs or outputs, just a function to be called:
/* function to be wrapped */
void HelloWorld () {
printf("Hello World\n");
}
Department of Computer Science — University of San Francisco – p.5/??
17-4:
Hello World
We need to create a Python object representing this
function:
PyObject *wrap_HelloWorld(PyObject *self, PyObject *args) {
HelloWorld();
return Py_BuildValue("");
}
Py_BuildValue builds up an object (in this case
’None’) to return.
Department of Computer Science — University of San Francisco – p.6/??
17-5:
Hello World
We also need to provide a mapping between method
names and the C functions that implement them.
/* List of all functions in the module */
static PyMethodDef hellomethods[] = {
{"HelloWorld", wrap_HelloWorld, METH_VARARGS },
{ NULL, NULL }
};
Department of Computer Science — University of San Francisco – p.7/??
17-6:
Hello World
Finally, we need some code to initialize and name the
module:
/* Module initialization function */
void inithello(void) {
Py_InitModule("hello", hellomethods);
}
Department of Computer Science — University of San Francisco – p.8/??
17-7:
Building Hello World
Now we need to compile this into a dynamically loadable
module. (.dll or .so, depending on your platform)
Python has a module called disutils that will make this
easy.
create a setup.py that will build and link the C code into a
loadable Python module.
You may need to copy the resulting module into the
current directory.
Department of Computer Science — University of San Francisco – p.9/??
17-8:
Dealing with input arguments
Translating input arguments from Python to C is a little
trickier:
void HelloWorld2(char *name) {
printf("Hello %s\n", name);
}
Department of Computer Science — University of San Francisco – p.10/??
17-9:
Dealing with input arguments
Our wrapper function needs to be able to create C
structures corresponding to Python objects.
Arguments are provided in a tuple, so we use
Py_ParseTuple to turn them into C structures.
PyObject *wrap_Hello2(PyObject *self, PyObject *args) {
char *name;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
HelloWorld2(name);
return Py_BuildValue("");
}
’s’ indicates one argument that is a string.
Department of Computer Science — University of San Francisco – p.11/??
17-10:
Dealing with return values
Most interesting functions also return something.
We need to convert C types back into Python objects
Py_BuildValue() does this
’i’ indicates an integer type
Department of Computer Science — University of San Francisco – p.12/??
17-11:
Dealing with return values
We can also return multiple values by putting them in a
tuple.
PyObject *wrap_gcdmult(PyObject *self, PyObject *args) {
int x,y,g;
if(!PyArg_ParseTuple(args, "ii", &x, &y))
return NULL;
g = gcd(x, y);
return Py_BuildValue("ii", g, y);
}
Department of Computer Science — University of San Francisco – p.13/??
17-12:
Automatically generating
wrappers
Writing interfaces by hand is fine for simple examples.
For large or complex pieces of code, it gets very tedious.
Debugging can be hard
Easy to introduce errors
Luckily, there are programs that automatically generate
interfaces.
We’ll look at SWIG
Department of Computer Science — University of San Francisco – p.14/??
17-13:
SWIG
SWIG stands for Simple Wrapper Interface Generator
Connects C/C++ programs to Perl, Python, Ruby, Tcl, C#,
Java
You define functions and variables in an intermediate
language and SWIG generates wrapper code.
Department of Computer Science — University of San Francisco – p.15/??
17-14:
SWIG example
Create an interface file:
%module example1
extern int factorial(int n);
Run SWIG: swig -python example1.i
build object modules: gcc -c example1.c
example1_wrap.c -I/usr/include/python2.3
Link into a shared library: gcc -shared
example1.o example1_wrap.o -o _example1.so
Department of Computer Science — University of San Francisco – p.16/??
17-15:
Working with existing libraries
SWIG can also parse existing C header files
This works very nicely for wrapping existing code.
We’re jsut scraping the surface of what can be done with
SWIG
Goal: give you a taste of the way in which scripting
languages can interact with ’systems’ languages.
Department of Computer Science — University of San Francisco – p.17/??
17-16:
SWIG
SWIG can make interfacing with an existing library very
simple.
Very nice for complex data access
Arrays, structs, etc.
Lets you use Python for its strengths (control, data flow)
and C for its strengths (efficiency).
Department of Computer Science — University of San Francisco – p.18/??