Indice

Integrare l'interprete Python in applicazioni C/C++

Autore: Fabio Di Matteo
Ultima revisione: 12/07/2008

risorse: Embedding Python in Your C Programs (Linux Journal)

E' possibile integrare nelle nostre applicazini C e C++ del codice scritto in python, anche prelevato da uno o più file esterni.
Per compilare queste applicazioni abbiamo bisogno dei pacchetti di sviluppo di python e ovviamente dell'interprete python.
I nostri programmi verranno lincati ad una libreria dinamica libpython2.5.so (per python 2.5) grazie agli header del python, di solito collocati in /usr/include/python2.5/ (per python 2.5).
Il nostro progetto è composto da 3 file, il main.c contenente il codice C, il makefile e un file di nome file.py con del codice python a piacere.

Il make file

Se si usa un'altra versione di python cambiare tutte le occorrenze di python2.5 con la versione che si vuole lincare.

CPP = gcc 
OPTS =  `python-config  --includes --libs --cflags --ldflags` -lpython2.5 -lm -L/usr/lib/python2.5/config


 

all:
	$(CPP) main.c -o main $(OPTS)

clean:
	rm main

Vorrei far notare che per le guide che ho trovato in rete nella seconda riga, nella variabile OPT, bastava soltanto python-config –includes –libs –cflags –ldflags, purtroppo nelle prove che ho fatto non è stato così, in quanto il comando python-config non riusciva a fornire al compilatore i giusti flag anche per la libreria condivisa libpython2.5.so . Come si può osservare ho risolto specificando il percorso . -lpython2.5 -lm -L/usr/lib/python2.5/config .

Il main.c

#include <stdio.h>
#include <python2.5/Python.h>
 
void exec_pycode(const char* code)
{
  Py_Initialize();
  PyRun_SimpleString(code); //esegue semplicemente l'istruzione contenuta in code
  Py_Finalize();
}
 
 
 
void exec_pyfile(char* filepy)
{
  FILE* f= fopen(filepy, "r");
 
  Py_Initialize();
  PyRun_SimpleFile(f, filepy); //esegue semplicemente le istruzioni contenute nel file filepy
  Py_Finalize();
  fclose(f);
}
 
 
int main(int argc, char* argv[] ){
 
 
printf("%s\n","Eseguo istruzione python  print 'Ciao python': ");
exec_pycode("print 'Ciao python'; ");
 
printf("%s\n","Eseguo istruzione python all'interno del file file.py : ");
exec_pyfile("file.py");
 
 
return 0;
}

Quali sono le dipendenze del nostro programma?

Andiamole a controllare con il comando ldd

ldd main

        linux-gate.so.1 =>  (0xffffe000)

	libpython2.5.so.1.0 => /usr/lib/libpython2.5.so.1.0 (0xb7db1000)

	libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb7d8c000)
	libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7c3e000)
	libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb7c26000)
	libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7c22000)
	libutil.so.1 => /lib/i686/cmov/libutil.so.1 (0xb7c1e000)
	/lib/ld-linux.so.2 (0xb7efa000)

Come si può vedere l'unica dipendenza legata al python è /usr/lib/libpython2.5.so.1.0, basterebbe distribuirla con il nostro programma (installandola nel path di ricerca delle librerie [/usr/lib o /usr/local/lib]) e dovremmo poter far a meno dell'interprete python.
Lo stesso si dovrebbe fare per eventuali moduli aggiuntivi.