Вы находитесь на странице: 1из 4

Python DESARROLLO

Enlazando Python con la realidad

REUTILIZACIN DE CODIGO

Python, Perl, Php, Ruby todos adolecen del mismo problema, tarde o temprano tendremos que volver al mundo real y trabajar con una librera C. POR JOS MARA RUIZ

a en los aos 70 la gente del mundo de la Ingeniera del Software comenz a imaginar un futuro donde slo se avanzara. No habra que volver a escribir programas para problemas ya resueltos. El famoso: No reinventes la rueda. Comenzaron a hablar de objetos y componentes. Desgraciadamente esta visin del futuro se pareca demasiado a esa otra en la que todos vamos en cohetes al trabajo y comemos en una hamburguesera que orbita alrededor de la Tierra. La realidad es ms extraa quin se imaginaba un ordenador en cada casa y todos conectados mundialmente? A da de hoy el cdigo ms reutilizado es que viene en forma de libreras, ya sea de funciones o de objetos. Pero la mayor parte de estas libreras, y especialmente en el mundo de Linux, han sido programadas en C o C++. Estos lenguajes, debido a mltiples factores, han sido los ms populares para el desarrollo de libreras y sistemas, y hoy por hoy siguen siendo insustituibles en muchos mbitos. De C se destacaba su portabilidad (es muy sencillo encontrar

o crear un compilador de C para una nueva arquitectura) mientras que de C++, su balance entre portabilidad y capacidad para grandes diseos. En este artculo vamos a ver cmo podemos hacer uso de una pequea librera C desde Python a travs de un ejemplo grfico.

Nuestra librera OpenGL en C


La librera que vamos a utilizar va a proveer una serie de funciones que nos permiten manipular objetos 3D a travs de OpenGL. A que suena rimbombante? En realidad no es tan difcil. No entraremos en detalles respecto a OpenGL, pero aclararemos un poco qu es. OpenGL es un estndar mundial creado por SGI (Silicon Graphics Interactive) para el desarrollo de aplicaciones 3D interactivas. Esto traducido a la informtica domstica significa juegos!. Todos los juegos multiplataforma que utilicen 3D estn programados utilizando OpenGL (DirectX, la otra alternativa, slo funciona bajo plataformas Microsoft, o sea en sistemas Intel con Windows).

OpenGL tiene un diseo simple, los objetos se componen de vrtices (un tringulo tiene 3 vrtices) y estos vrtices definen reas que pueden tener una serie de propiedades como puede ser color o brillo. Una vez definidos los objetos pasamos a crear una serie de funciones que sern llamadas cuando se produzcan eventos. OpenGL utiliza un bucle infinito que, bsicamente, se dedica a recoger un evento, por ejemplo, la pulsacin de una tecla por parte del usuario, para, a continuacin, llamar a la funcin que se dedica a gestionarlo. As de simple. Evidentemente hacer un videojuego 3D es una tarea muy complicada, pero la base es esa, hacer que las imgenes en pantalla reaccionen a eventos que se disparan en cualquier momento y que la reaccin sea en tiempo real, o sea, que el usuario no perciba demora en el tiempo de reaccin. Todos hemos actualizado nuestra tarjeta grfica alguna vez para que la sensacin, a ms frames por segundo mejor, fuese ms realista. En el Listado 1 (descargable desde [5]) podemos ver un programa OpenGL muy

WWW.LINUX- MAGAZINE.ES

Nmero 09

57

DESARROLLO Python

simple, pero que ser la base para nuestra librera. Para compilarlo deberemos ejecutar make listado1 en el mismo directorio en que est, copiando a ese directorio el contenido del Listado 2 (descargable desde [5])a un fichero llamado Makefile. Y qu hace nuestro programa? Pues nuestro programa base genera un cubo 3D con texturas y lo gira sin parar hasta que pulsamos la tecla 2. Entonces lo detiene, comenzando a girar de nuevo cuando pulsemos la tecla 1. Con los tres botones del ratn podemos cambiar el ngulo en el que gira el cubo. Si compilamos el programa tal cual obtendremos un ejecutable que podremos usar. La velocidad a la que gire el cubo depende de la potencia del equipo de cada uno. Ahora necesitamos algo para pegar cdigo C con Python, y ese algo es SWIG.

SWIG
SWIG es una aplicacin desarrollada en 1995 en el departamento de Fsica Terica del Los lamos National Laboratory (ver [1] en Recursos). Fue all donde se desarroll la primera bomba atmica y desde entonces ha sido un centro puntero en investigacin a nivel mundial. El objetivo era el de reducir la complejidad de muchas aplicaciones cientficas donde es obligado el uso de lenguajes de bajo nivel, como C o Fortran. Desgraciadamente con estos lenguajes es muy complicado, por ejemplo, desarrollar GUI que a da de hoy son imprescindibles. Tambin son lenguajes

complicados que slo deben ser usados por expertos, y la mayor parte del personal de Los lamos son cientficos con poca preparacin en programacin. As que tenemos potentsimas libreras C y Fortran desarrolladas en lenguajes que no son capaces de usar sus destinatarios. Qu hicieron los ingenieros de Los lamos para simplificar el uso de estas potentes herramientas de clculo? Pues se dedicaban a crear libreras que permitiesen manejarlas desde lenguajes ms expresivos, como pueden ser Perl o Python. Este proceso, a la vez que laborioso, es altamente repetitivo, de manera que decidieron no volver a tener que pasar por l. Desarrollaron SWIG que, de forma casi automtica, genera todo el cdigo necesario para utilizar desde multitud de lenguajes de alto nivel (desde Python hasta OCaml pasando por Java o C#) libreras de C. Lo de casi automtico es esencial. Slo tenemos que generar un fichero de interfaz (acabado en extensin .i) y SWIG generar un fichero <nombre>_wrap.c que compilaremos junto al original para crear la librera. De esta manera obtendremos una librera dinmica (esos ficheros .so que podemos ver a miles en /usr/lib), as como una librera en el lenguaje de destino. En nuestro caso ese lenguaje ser Python.

El programa OpenGL.
En el Listado 1 vimos un programa de ejemplo en OpenGL. Es bsicamente un cubo, que gira y responde a eventos. Tiene una serie de propiedades que no podemos alterar, como la velocidad de giro o el color. En el Listado 3 (descargable desde [5])veremos la librera equivalente necesaria para nuestros propsitos. Examinmosla.

Para comenzar, al ser una librera no puede tener funcin main, as que la hemos renombrado arranque(). Se han incorporado nuevas funciones con el objetivo de poder modificar algunas caractersticas del objeto (color, velocidad, ttulo de la ventana). OpenGL (ver [2] en recursos) se compone de las libreras GL, GLU y GLUT. Esta ltima es muy importante, pero desgraciadamente la librera GLUT estndar tiene un defecto ( o problema, segn como se mire). La funcin glutMainLoop() es el bucle infinito de gestin de eventos. Se entra en ella pero jams se sale. Cuando se dispara el evento que provoca la salida del bucle, el programa acaba. Cualquier cosa que pongamos detrs de la llamada a glutMainLoop() no se ejecutar jams. Eso no parece muy lgico no? y si quiero poder arrancar el gestor de eventos, pararlo y volver a arrancar? Como no somos los nicos con este problema (casi todo el mundo piensa que es un problema ;) unos valientes, en la mejor tradicin del software libre, han creado FreeGLUT (ver [3] en Recursos para ms informacin). Bsicamente es igual a GLUT solo que, entre otras cosas, nos permite salir del bucle interno de glutMainLoop() pero sin que finalice el programa. Y por qu queremos que ocurra esto? Pues porque necesitamos una librera, queremos que la funcin arranque() vuelva al programa principal (que ser nuestro intrprete de Python) una vez que finalice su ejecucin, en lugar de finalizar todo el programa. Este un un problema tpico que nos podemos encontrar al crear libreras para Python usando libreras C. A veces lo que queremos usar son las funciones de un programa ya existente (por ejemplo, imagina poder acceder a las funciones que tiene Mozilla o Firefox para RSS o anlisis de HTML), as que los pasos sern: elimina los puntos de salida del programa (generalmente los exit()) y elimina el main. As ya tendremos nuestra librera, lista para ejecutar SWIG sobre ella.

El archivo de interfaz para SWIG


SWIG (ver [4] en Recuros) necesita un archivo que le diga qu funciones y definiciones de datos exportar a Python. Este

58

Nmero 09

WWW.LINUX- MAGAZINE.ES

Python DESARROLLO

para aislar cdigo especfico para SWIG respecto de las libreras originales. Y bueno, casi hemos acabado, slo nos queda Figura 1: El cubo inicial tal y como Figura 2: Con las teclas podemos declarar los se ve en la ventana del programa. modificar su posicin y giro. tipos de datos y cabeceras necesarias. Podemos ver las fichero se parece mucho a los ficheros de definiciones en el Listado 4 (descargable cabeceras (o headers, mirar en en [5]). Bsicamente son las cabeceras /usr/include para ver unos cuantos) de de las funciones que queremos usar C. El fichero comienza con la sentencia: desde Python con la palabra extern delante. Esta palabra le dice a SWIG que %module listado3 son funciones que existen en un fichero externo. Que declara el nombre del mdulo y debe ser igual al nombre de nuestra Las palabras mgicas librera C. Este nombre ser exportado a cada lenguaje de manera que se corresYa tenemos casi lista la pocin, ahora ponda con la estructura de organizacin slo tenemos que usar las palabras mgique en l exista. En el caso de Python el cas del Listado 5 (descargable en [5]). nombre del mdulo se corresponder ste muestra un fichero Makefile que ya con un paquete. usamos para compilar el Listado 1, ahora El resultado final de la ejecucin de tenemos que ejecutar: SWIG ser un fichero llamado listado3_wrap.c. Es un fichero en lenguaje C, > make que define una serie de funciones que nos permitirn acceder a la librera listaY se realizar la ejecucin de las rdedo3.c definidas en listado3.i. nes: Algunas de las definiciones que pondremos en listado3.i devuelven datos de swig -python listado3.i tipos definidos en OpenGL, por lo que gcc -c -fPIC listado3.c $(INCS) tendremos que decirle a SWIG que en el gcc -c -fPIC listado3_wrap.cU fichero listado3_wrap.c debe incorporar $(PYINCS) $(INCS) la cabecera: gcc -shared listado3.cU
#include <GL/glut.h> listado3_wrap.c -o _listado3.soU $(INCS) $(PYINCS) $(LIBS)U $(PYLIBS)

hay que compilarlos. De eso se encargan los tres siguientes comandos. El primero compila nuestra librera, el segundo los ficheros generados por SWIG y el tercero lo une todo para generar la librera dinmica. Esos $(INC) o PYLIBS son opciones de compilacin guardadas en variables de control en el Makefile, varan de sistema en sistema, pero las que aparecen en el Listado 5 son las ms genricas.

Nueva librera
Por increble que parezca hemos acabado, ya tenemos nuestra librera. Si miramos en el directorio en el que hemos estado realizando todas las acciones veremos un fichero llamado _listado3.so. Es una librera dinmica que puede ser cargada en cualquier momento. A qu esperamos? Arranquemos nuestro intrprete de Python:
> python Python 2.4 (#2, Apr 3 2005,U 22:24:02) [GCC 3.4.2 [FreeBSD] 20040728]U on freebsd5 Type "help", "copyright",U "credits" or "license" for moreU information. >>> import listado3 >>>

Con la orden import acabamos de cargar la librera y la tenemos disponible para su uso. Comencemos con la accin ms simple, arranquemos el programa con las opciones por defecto:
>>>listado3.arranque()

Esto se hace mediante la declaracin:


%{ #include <GL/glut.h> %}

Entre los smbolos %{ y %} podemos introducir cualquier declaracin extra o incluso cdigo que no exista en el fichero listado3.c. Digamos que es una manera

El primer comando genera el fichero listado3_wrap.c, as como listado3.py. Hay una opcin, -python que podramos cambiar por -perl o -java. Esta opcin controla el lenguaje que se utilizar para generar la librera. Pero claro, estos ficheros no son ms que cdigo,

Cuando pulsemos INTRO aparecer una ventana en la pantalla con un objeto que se mueve a gran velocidad. Es nuestro cubo, lo que ocurre es que se mueve demasiado rpido. Si pulsamos la tecla 2, el cubo se detendr, para ponerlo de nuevo en movimiento debemos pulsar 1.

WWW.LINUX- MAGAZINE.ES

Nmero 09

59

DESARROLLO Python

Si pulsamos, con el cubo girando, con los botones del ratn sobre la ventana, veremos que cada botn cambia la direccin de giro del cubo en un sentido distinto. Cuando nos aburramos del cubo, o estemos mareados si nuestro ordenador es muy rpido, pulsaremos q y la ventana desaparecer. Volveremos a ver el prompt >>> de Python. Esto ya es todo un logro, hemos ejecutado una funcin C que interacta con OpenGL desde Python!. Pero an as apenas hemos hecho nada, tambin lo podramos haber hecho con un script BASH! Vamos a interactuar ms con la librera. Si miramos el fichero de interfaz listado3.i que est en el Listado 4 veremos las funciones que estn disponibles para su uso desde Python. Cambiemos la velocidad de giro de manera que podamos ver el cubo.
>>> listado3.setTiempoEsperaU (10000000) >>> listado3.arranque()

last): File "<stdin>", line 1, in ? OverflowError: argument numberU 1: long int too large toU convert to int >>>

ces 0 y 1 no tienen porqu estar en el sentido correcto. Se puede jugar con el cdigo del Listado 5 para intentar conseguir otros colores.

Conclusin
No resulta tan complicado acceder a miles de libreras en C desde Python, en la propia documentacin de SWIG aparece como ejemplo generar una librera Python de manera casi automtica para la famosa librera GD de dibujo 2D. Seguro que la prxima vez que veamos una nueva librera para Python nos preguntaremos si los autores han usado SWIG, puede que incluso lo pudiramos haber hecho nosotros ;) s

>>> listado3.setTiempoEsperaU (5000000000) Traceback (most recent callU

60

Nmero 09

WWW.LINUX- MAGAZINE.ES

EL AUTOR

Para no complicar el cdigo (debera haber usado nanosleep de la librera C estndar) se ha introducido un bucle que itera un nmero determinado de veces en la funcin display() de listado3.c. Esta funcin es invocada por OpenGL para dibujar en pantalla los objetos, si se introduce un retraso en ella tardar ms en realizar su trabajo. Eso se traduce en que podremos ver mejor el cubo girando si hacemos que el retraso sea el adecuado. En nuestro sistema, un valor de 10.000.000 de iteraciones hace que el cubo se vea girar de manera suave. Evidentemente al ser un bucle, depende de la velocidad del sistema. No es la manera ms elegante de introducir un retraso, pero s la ms simple y corta (nuestras pginas son limitadas). La variable espera en listado3.c es de tipo INT. Eso significa que su valor mximo ser un poco ms de 4.000.000.000 qu ocurre si introduzco un retraso de 5.000.000.000?

Python se queja!, diciendo que la asignacin no se puede realizar. Un fallo de este tipo en un programa C nos hubiera llevado a un fallo irreversible que abortara el programa. Pero en Python no, simplemente llegamos de nuevo al intrprete. Esta es una de las razones por las que es interesante utilizar Python sobre libreras C, eliminamos muchos errores fatales porque Python verifica por nosotros los tipos de datos y es capaz de recuperarse de los errores. Juguemos con los colores del cubo. El cubo tiene 6 caras y lo normal sera darle un color a cada cara, pero en OpenGL se le dan colores a los vrtices. Como el cubo tiene 8 vrtices tenemos que asignar 8 colores. Qu color tendr el cubo en el centro de una de sus caras si cada vrtice tiene un color? Pues siguiendo la jerga de OpenGL tendr un color interpolado, una mezcla de los 4 colores de los vrtices. Una de nuestras funciones nos permite definir el color de los vrtices (setColor()), as que vamos a hacer que las caras sean de color gris. A un vrtice le damos color negro y al siguiente blanco. En el Listado 5 podemos ver un programa que asigna colores blanco y negro alternativamente a los vrtices. El resultado no es del todo gris, por qu? Porque depende de la manera en que fueron definidos los vrtices. Los vrti-

RECURSOS
[1] Los lamos National Laboratory: http://www.lanl.gov [2] OpenGL: http://www.opengl.org [3] Proyecto FreeGLUT: http://freeglut. sourceforge.net [4] Proyecto SWIG: http://www.swig.org [5] Descarga de los listados de este artculo: http://www.linux-magazine.es/ Magazine/Downloads/09

Jos Mara Ruiz actualmente est realizando el Proyecto Fin de Carrera de Ingeniera Tcnica en Informtica de Sistemas mientras estudia Fsica. Lleva 8 aos usando y desarrollando software libre y, desde hace dos, se est especializando en FreeBSD. Pedro Orantes est cursando 3 de Ingeniera Tcnica en Informtica de Sistemas y en sus ratos libres toca en un grupo de msica.

Вам также может понравиться