Download Printable - USF Computer Science

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
17-0:
Using C code from Python
Sometimes, you might want to call C/C++ code from
Python.
Programming Language Paradigms
What are some examples?
Extending Python with C
Chris Brooks
Department of Computer Science
University of San Francisco
Department of Computer Science — University of San Francisco – p.2/??
Department of Computer Science — University of San Francisco – p.1/??
17-1:
Using C code from Python
Sometimes, you might want to call C/C++ code from
Python.
17-2:
Using C code from Python
Optimize performance
There are two approaches to combining C ond Python
Write wrapper code by hand.
Use an automatic wrapper generator
Interface with a third-party package
We’ll take a brief look at each.
Integrate legacy code into a new application.
Department of Computer Science — University of San Francisco – p.3/??
17-3:
Hello World
Let’s start with Hello World.
No inputs or outputs, just a function to be called:
Department of Computer Science — University of San Francisco – p.4/??
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("");
}
/* function to be wrapped */
void HelloWorld () {
printf("Hello World\n");
Py_BuildValue builds up an object (in this case
’None’) to return.
}
Department of Computer Science — University of San Francisco – p.5/??
Department of Computer Science — University of San Francisco – p.6/??
17-5:
Hello World
17-6:
Hello World
We also need to provide a mapping between method
names and the C functions that implement them.
Finally, we need some code to initialize and name the
module:
/* List of all functions in the module */
static PyMethodDef hellomethods[] = {
{"HelloWorld", wrap_HelloWorld, METH_VARARGS },
{ NULL, NULL }
};
/* Module initialization function */
void inithello(void) {
Py_InitModule("hello", hellomethods);
}
Department of Computer Science — University of San Francisco – p.8/??
Department of Computer Science — University of San Francisco – p.7/??
17-7:
Building Hello World
17-8:
Dealing with input arguments
Now we need to compile this into a dynamically loadable
module. (.dll or .so, depending on your platform)
Translating input arguments from Python to C is a little
trickier:
Python has a module called disutils that will make this
easy.
void HelloWorld2(char *name) {
printf("Hello %s\n", name);
}
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-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("");
}
Department of Computer Science — University of San Francisco – p.10/??
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
’s’ indicates one argument that is a string.
Department of Computer Science — University of San Francisco – p.11/??
Department of Computer Science — University of San Francisco – p.12/??
17-12:
17-11:
Dealing with return values
We can also return multiple values by putting them in a
tuple.
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
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);
}
Luckily, there are programs that automatically generate
interfaces.
We’ll look at SWIG
Department of Computer Science — University of San Francisco – p.13/??
17-13:
Department of Computer Science — University of San Francisco – p.14/??
17-14:
SWIG
SWIG stands for Simple Wrapper Interface Generator
Create an interface file:
Connects C/C++ programs to Perl, Python, Ruby, Tcl, C#,
Java
%module example1
extern int factorial(int n);
You define functions and variables in an intermediate
language and SWIG generates wrapper code.
Run SWIG: swig -python example1.i
SWIG example
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/??
Department of Computer Science — University of San Francisco – p.15/??
17-15:
Working with existing libraries
SWIG can also parse existing C header files
This works very nicely for wrapping existing code.
17-16:
SWIG
SWIG can make interfacing with an existing library very
simple.
We’re jsut scraping the surface of what can be done with
SWIG
Very nice for complex data access
Arrays, structs, etc.
Goal: give you a taste of the way in which scripting
languages can interact with ’systems’ languages.
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.17/??
Department of Computer Science — University of San Francisco – p.18/??