Marco Barisione Estendere Python in C.

Slides:



Advertisements
Presentazioni simili
Puntatori Linguaggio C.
Advertisements

Introduzione al linguaggio C++
Una applicazione complessa non può essere sviluppata in un unico file: sarebbe ingestibile! Deve necessariamente essere strutturata su più file sorgente.
Introduzione al linguaggio C
PUNTATORI Introduzione
PHP.
Differenze tra C e C++ Commenti: Adesso puoi inserire dei commenti tra // e la fine della linea. Usare le librerie C: In C++ puoi anche chiamare una funzione.
Introduzione al linguaggio C Dr. Francesco Fabozzi Corso di Informatica.
Anno accademico Il preprocessore del linguaggio C.
Fondamenti di Informatica I a.a Il linguaggio C Il preprocessore La sostituzione di macro Le compilazioni condizionali Linclusione di file C.
Anno accademico Array e puntatori in C.
Programmazione Procedurale in Linguaggio C++
Indirizzi delle variabili A ogni variabile sono associati tre concetti fondamentali: il valore memorizzato; il tipo dati di appartenenza; lindirizzo. Il.
FUNZIONI DI BIBLIOTECA
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Caratteri e stringhe di caratteri
Argomenti dalla linea dei comandi Gli argomenti possono essere passati a qualsiasi funzione di un programma, compresa la main(), direttamente dalla linea.
Funzioni definite dall’utente
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Corso di Fondamenti di programmazione a.a. 2009/2010 Prof.ssa Chiara Petrioli.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 21 Marzo 2013.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 4 Aprile 2013.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Stringhe e Puntatori Marco D. Santambrogio – Ver. aggiornata al 18 Marzo 2013.
Process synchronization
1 Programmazione ad oggetti in Java E.Mumolo, DEEI
Laboratorio di Linguaggi lezione VI: puntatori 2/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.
Laboratorio di Linguaggi P R I M O C O M P I T I N O Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese.
1 Corso di Laurea in Biotecnologie Informatica (Programmazione) Introduzione a JAVA Anno Accademico 2009/2010.
1 Corso di Informatica (Programmazione) Lezione 13 (21 novembre 2008) Programmazione in Java: stringhe e array.
Introduzione al linguaggio Java
Procedure e funzioni nei linguaggi di alto livello Lab Programmazione - turno /2006.
Approfondimento delle classi
Le classi Definizione di classe Attributi e metodi di una classe Costruttori e distruttori Private e public Funzioni friend Il puntatore this.
A.A. 2010/2011Ambienti di Programmazione per il Software di Base1 (Es. – 6) Ambienti di Programmazione per il Software di Base Le Stringhe in C Input.
Struct, enum, Puntatori e Array dinamici
Esercizi FUNZIONI Passaggio di parametri per valore, variabili e tipi locali e globali, prototipo.
Strutture di controllo in C -- Flow Chart --
Esercizi Puntatori, struct con campi puntatore, puntatori a struct, rapporto tra array e puntatori. FUNZIONI Passaggio di parametri per indirizzo, passaggio.
I File.
PROGRAMMARE IN C Un ambiente di sviluppo `e un software che serve per scrivere ed eseguire programmi. Generalmente integra almeno 3 funzionalita’: Editor:
2000 Prentice Hall, Inc. All rights reserved. Capitolo 10 (Deitel) Strutture, unioni ed enumerazioni Sommario Introduzione Definire le strutture.
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Corso di Fondamenti di programmazione a.a. 2009/2010 Prof.ssa Chiara Petrioli.
Unità Didattica 3 Linguaggio C
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Array e stringhe Marco D. Santambrogio – Ver. aggiornata al 9 Agosto 2013.
C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.
Fopndamenti di programmazione. 2 La classe String Una stringa è una sequenza di caratteri La classe String è utilizzata per memorizzare caratteri La classe.
1Piero Scotto - C14. Finalità del corso Programma Materiale Requisiti Spendibilità 2Piero Scotto - C14.
Sviluppare un programma in C che, dato un array da 100 elementi interi caricato con numeri casuali compresi tra [10,100], sia in grado di cercare il valore.
Unità Didattica 1 Linguaggio C
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Approfondimenti sulle Classi.
Astrazione procedurale ed eccezioni
CORSO DI PROGRAMMAZIONE II Lezione 22
Programmazione in linguaggio C
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Corso di Programmazione 1 a.a.2006/2007 Prof.ssa Chiara Petrioli Corso di Laurea.
Introduzione a Javascript
Variabili Numeriche –Interi (byte, short, int, long): complemento a 2 –A virgola mobile (float, double): IEEE 745 Alfanumeriche –Carattere (char): Unicode.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 11 Ottobre 2014.
Università di Torino – Facoltà di Scienze MFN Corso di Studi in Informatica Programmazione I - corso B a.a prof. Viviana Bono Blocco 7 – Array.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a – 3° ciclo.
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 7 Tipi di dato e strutture dati Specifica e realizzazione di strutture informative come classi.
1 Eccezioni in Java. 2 Ricordiamo che 4 una procedura può terminare –normalmente, ritornando un risultato –in modo eccezionale ci possono essere diverse.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 11 Marzo 2014.
1 Il linguaggio C Precisazioni sull’esperienza in laboratorio.
ALLOCAZIONE STATICA: LIMITI Per quanto sappiamo finora, in C le variabili sono sempre dichiarate staticamente –la loro esistenza deve essere prevista e.
Il linguaggio C Puntatori e dintorni.
Sommario Oggetti immutabili e non Tipi Primitivi: String, Arrays.
Copyright © Istituto Italiano Edizioni Atlas
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 8 Aprile 2015.
Il C `e un linguaggio di programmazione di uso generale, originariamente sviluppato per la scrittura del sistema operativo Unix, ed oggi disponibile su.
Transcript della presentazione:

Marco Barisione Estendere Python in C

Perché estendere Python? La maggior parte del tempo di esecuzione è passata ad eseguire poche funzioni Queste funzioni scritte in Python potrebbero non essere abbastanza veloci Utilizzare codice preesistente o librerie esterne Interfacciarsi direttamente ad hardware

Perché non usare le API Python? Python fornisce una API completa ed estesa, perché non usarla direttamente? Bassa produttività Lavoro noioso e ripetitivo, quindi fonte di errori Serve molto codice per cose stupide Mai fare manualmente un lavoro che può essere fatto altrettanto bene (se non meglio) da un tool automatico

SWIG Cos’è SWIG? SWIG = “Simplified Wrapper and Interface Generator” Parte da dichiarazione in C per generare il codice di interfaccia con Python Facile da usare Quasi tutto automatico Può essere direttamente richiamato da make (o da un programma analogo) Si può scrivere codice C senza preoccupari dell’integrazione con Python Parte da un file sorgente C (“.c”), da un header (“.h”) o, meglio, da un file di interfaccia (“.i”)

Come lavora SWIG Si scrive la libreria in C (“modulo.c” ad esempio) Si scrive un file di interfaccia (“modulo.i”) Si esegue SWIG sul file di interfaccia (che produce “modulo_wrap.c” e “modulo.py”) swig –python modulo.i Si compilano i sorgenti e si linkano in un file “_modulo.so” su Unix o “_modulo.pyd” su Windows Il file sorgente “modulo.c” può essere linkato staticamente, cioè direttamente nel file di estensione Dinamicamente, cioè in una altra libreria esterna. Utile in particolare se la libreria deve essere usata da altre applicazioni non Python o non sono disponibili i sorgenti

Perché usare un file di interfaccia SWIG può essere egeguito direttamente su un header o un file sorgente C Potrebbero essere esportate funzioni che non serve utilizzare da Python SWIG non è un compilatore, potrebbe non gestire correttamente parte della sintassi del C In caso si decida comunque di utilizzarlo su un header o sorgente si possono inserire istruzioni specifiche #ifdef SWIG /* SWIG definisce questa macro */ /* Codice specifico di SWIG */ #endif

Un primo esempio (1) Supponiamo di avere un file sorgente C (“somma.c”) contenente solo una funzione somma #include "somma.h" int somma(int a, int b){return a + b;} E il relativo header (“somma.h”) extern int somma(int a, int b); Ora è necessario scrivere il file di interfaccia %module somma %{ %} /* Si poteva usare %include "somma.h" */

Un primo esempio (2) Le linee che iniziano con “%” sono comandi specifici di SWIG “%module somma” indica a SWIG che il nome del modulo (quello poi usato da Python) sarà “somma” Il codice racchiuso fra “%{” e “%}” viene incluso direttamente in “somma_wrap.c” Vista la semplicità del codice si poteva includere direttamente l’header con “%include” Vi è un’importante differenza fra i due “include” “%include” include un file affinché sia interpretato da SWIG “#include” serve per fare includere l’header dal compilatore, questo necessita, infatti, di conoscere il prototipo delle funzioni in “somma_wrap.c”

Un primo esempio (3) Ora si può procedere alla creazione del modulo, ad esempio utilizzando il seguente makefile somma.so: somma.i swig -python somma.i gcc -shared -o _somma.so somma.c \ somma_wrap.c clean: rm somma_wrap.c somma.py _somma.so *.o Ovviamente il file necessari, come “Python.h”, devono essere trovabili da gcc. I moduli devono essere compilati con lo stesso compilatore usato per compilare l’interprete

Un primo esempio (4) Il file “.so” o “.pyd” generato contiene le interfacce di basso livello Il file “.py” può essere usato da Python come un normale modulo >>> import somma >>> print somma <module 'somma' from 'somma.py'> >>> dir(somma) ['__doc__', '__file__', '__name__', 'somma'] >>> print somma.somma(5, 3) 8

Variabili e costanti (1) È possibile accedere da Python anche a variabili globali C e tradurre “#define” ed enumerazioni in variabili File sorgente “var.c” #include "var.h" int a = 42; File header “var.h” #define X 12 enum{ZERO, UNO, DUE}; int a; File di interfaccia “var.i” %module var %{#include "var.h"%} %include var.h /* SWIG esamina l’header */

Variabili e costanti (2) Ora è possibile compilare il file ed usare il modulo >>> import var >>> print var.ZERO, var.UNO, var.DUE 0 1 2 >>> print var.X 12 >>> print var.cvar.a 15 >>> var.ZERO = 42 >>> print var.ZERO 42

Variabili e costanti (3) Le enumerazioni e le “#define” diventano nuove variabili Python Non costanti! Modifica solo per Python, nel modulo C non cambiano Infatti non sono variabili ma sono espanse dal preprocessore L’accesso alle variabili avviene attraverso “nome_modulo.cvar.nome_variabile” In caso di modifica il loro valore è modificato anche per il codice C

Variabili immutabili Una variabile globale può essere resa costante dichiarandola come “const” o con “%immutable” %immutable; // Le variabili seguenti // sono costanti int a; %mutable; // Le variabili seguento sono // non costanti Oppure const int a; // Solo questa costante Un tentativo di assegnamento ad una variabile costante produce un’eccezione

Tipi base in SWIG I tipi base sono interpretati correttamente da SWIG e tradotti nel tipo Python equivalente I puntatori sono tradotti in stringhe contenenti anche informazioni sul tipo Comunque Python non potrebbe usare direttamemente i puntatori Il codice generato da SWIG può effettuare controlli sui tipi Esempio: int* → “_1008e124_p_int” double** → “_f8ac _pp_double” char** → “_10081012 _pp_char” double*** → “_f8bc _ppp_double”

Tipi “complessi” in SWIG Tutti gli altri tipi (strutture, array ecc.) sono considerati puntatori Nel file di interfaccia non è necessario definire le strutture Avviene quasi sempre la cosa giusta In alcuni casi è necessario usare “typedef” C: void foo(size_t num); Python: foo(40) → Errore! (si aspettava _p_size_t) Per risolvere: typedef unsigned int size_t; Come per “%include” anche “typedef” è un’istruzione solo per SWIG, il compilatore deve comunque sapere le eventuali “typedef”

Strutture (1) Se le strutture sono definite nell’interfaccia allora sono trasformate in classi Python >>> import point >>> p = point.Point() >>> p.x = 13 >>> print p.x, p.y 13 0 point.h struct Point{ int x, y; }; point.i %module point %{#include "point.h"%} %include point.h

Strutture (2) In C non è possibile avere funzioni in una struct, in SWIG sì %module point %{ #include "point.h" %} %include point.h %extend Point{ struct Point __add__(struct Point *other){ struct Point ret; ret.x = self->x + other->x; ret.y = self->y + other->y; return ret; } };

Strutture (3) Il costruttore in SWIG (come in C++) ha il nome della struttura Il distruttore in SWIG ha il nome della struttura preceduto da “~” È frequente che esistano funzioni che svolgano la funzione di metodi. Queste possono essere aggiunte automaticamente se seguono determinate regole %extend Strutt{ Strutt(); /* Chiama "new_Strutt()" */ ~Strutt(); /* Chiama "delete_Strutt()" */ metodo(); /* Chiama "Strutt_metodo()" */ };

Parametri di ingresso ed uscita (1) In C è frequente usare degli argomenti come parametri di uscita o di ingresso void add(int x, int y, int *r){ *r = x + y; } int sub(int *x, int *y){ return *x - *y; void negate(double *x){ *x = -(*x);

Parametri di ingresso ed uscita (2) Tutto ciò può essere reso più aderente al modo di gestire gli argomenti di Python %module inout %{#include "inout.h"} %include "typemaps.i" void add(int, int, int *OUTPUT); int sub(int *INPUT, int *INPUT); void negate(double *INOUT); Ed usato quindi come a = inout.add(3,4) → a = 7 b = inout.sub(7,4) → b = 3 c = inout.negate(4) → c = - 4

Array Gli array sono considerati come puntatori Non vi è conversione automatica con le liste o un’altro tipo simile poiché: Pesanti problemi di prestazioni se l’array è troppo grande In C non c’è modo di conoscere le dimensioni di un array Il C fa poca distinzione fra puntatori e array La distinzione è nulla se gli array sono passati a funzioni

Unbounded C arrays Non c’è bound checking int sum(int a [], int n){ int i, sum = 0; for (i = 0; i < n; ++i){sum += a[i];} return sum; } %include "carrays.i" %array_class(int, array_interi); a = array_interi(5) for i in range(5): a[i] = i sum(a, 5) → 10 Non c’è bound checking

Puntatori a char (char *) Se l’input di una funzione C è un “char *” allora si può passare una stringa Python come argomento /* C */ void foo(char *s); # Python foo("Hello") La stringa passata non può essere modificata e non può contenere “\0” Se una funzione C ritorna un “char *”, questo viene copiato in una stringa Python Il valore ritornato non può contenere “\0” Attenzione ai memory leak

Passare stringhe binarie /* C */ void foo(char *str, int len); /* Interfaccia */ %apply (char *STRING, int LENGTH) { (char *str, int len) }; int foo(char *str, int len); # Python foo("Hello\0World")

Rilasciare la memoria Se un oggetto ritornato è stata creato con “malloc” deve essere anche distrutto con “free” È possibile rendere l’operazione automatica con “%newobject” /* C */ char *foo(){ char *ret = (char *)malloc(...); return ret; } /* Interfaccia */ %newobject foo; char *foo();

Rinominare le funzioni È possibile rinominare le funzioni in modo che il loro nome sia diverso in Python da quello C Il nome della funzione C potrebbe essere una keyword in Python Il nome C potrebbe avere un prefisso per evitare collisioni che in Python possono essere evitate con i moduli È infatti tipico vedere funzioni C con nomi come “mia_libreriaStampa()” /* Interfaccia */ %rename(my_print) print; extern void print(char *);