Packaging C/C++ per Python con SWIG — Set 1

| | | | | | | | | | |

Non c`è dubbio che Numpy, esegue un`enorme quantità di attività ? In effetti, le librerie come Numpy non sono scritte interamente in Python, alcune parti della libreria sono scritte in C, il che fornisce prestazioni migliori. Dopo aver scritto il codice C, lo avvolgiamo nel codice Python, che funge da interfaccia per quei codici C. Possiamo quindi chiamare le funzioni C usando la sintassi Python, dove l`elaborazione effettiva viene eseguita in C dietro le quinte e il risultato viene restituito come oggetto Python. In questo articolo vedremo come creare un wrapper Python per il nostro programma C su sistemi Linux utilizzando il software SWIG .

Cos`è SWIG >

In poche parole, SWIG — è un compilatore che accetta dichiarazioni C/C++ e lo avvolge per accedere a quelle dichiarazioni da altri linguaggi come Python, Tcl, Ruby, ecc.
Di solito questo non richiede modifiche al codice esistente e crea un`interfaccia entro un minuto.

Motivi per creare un wrapper

In molti casi abbiamo bisogno di wrapper, i seguenti sono —

  • Costruire un`interfaccia interpretata per i programmi C esistenti.
  • Costruire moduli C ad alte prestazioni per linguaggi di scripting ‚Äã‚Äã
  • Testare enormi programmi C è molto difficile, quindi scriviamo wrapper in alcuni linguaggi di scripting ‚Äã‚Äãcome Python dove è molto facile scrivere dei test. etc

Installazione di SWIG

Per scaricare SWIG direttamente dal repository apt, inserisci i seguenti comandi —

sudo apt-get update sudo apt-get install swig 

Scrivere un wrapper usando SWIG

Diamo un`occhiata a questo pezzo di codice in C con due funzioni e una variabile globale —


/ * file: gfg.c * /


# include "stdio.h >
# include "matematica.h >


// il nostro file di intestazione
# include "gfg.h"
# define ll long long


double myvar = 3.4;


// calcola fattoriale

ll int fact (ll int n)

{

se (n "= 1)

return 1;

else

return (n * fact (n-1));

}


// trova la mod

int my_mod ( int n, int m )

{

return (n% m);

}

Ecco il nostro file di intestazione — ;


long long int fact ( long long int n);

int my_mod ( int n, int m);

Per prima cosa dobbiamo creare il file di interfaccia SWIG . Questo file contiene prototipi di funzioni ANSI C e dichiarazioni di variabili. Qui —

  • La direttiva % module specifica il nome del modulo che useremo in Python.
  • % {. . % } fornisce una posizione per inserire codice aggiuntivo, come file di intestazione C o dichiarazioni C aggiuntive, nel codice wrapper generato.
  • La direttiva % include ci consente di includere file aggiuntivi come i file di intestazione.

/ * file: gfg.i * /


/ * nome del modulo utilizzato * /
% module gfg
% {

/ * Tutto in questo file viene copiato nel

file wrapper. Includere il file di intestazione C richiesto

compilare l`interfaccia * /

# include "gfg.h"

/ * dichiarazione di variabile * /

double myvar;

%}


/ * elenca esplicitamente funzioni e variabili per l`interazione * /

double myvar;

lungo lungo int fact ( long long int n1);

int my_mod ( int m, int n);


/ * o se vogliamo collegare tutte le funzioni, allora possiamo semplicemente

include un file di intestazione come questo -

% include & quot; gfg.h & quot;

* /

Ora creeremo il codice wrapper usando un comando come

$ swig -python gfg.i 

Questo comando genera un codice wrapper chiamato "gfg_wrap.c" . Questi file contengono una versione gonfia del nostro codice sorgente C con codice di gestione degli errori diverso, ecc. Generato un altro file "gfg.py", che è il modulo che stiamo importando nel nostro script python.


Dopodiché dobbiamo generare codice indipendente dalla posizione da utilizzare nella libreria condivisa compilando "gfg_wrap.c" e "gfg .c" con il seguente comando:

$ gcc -c -fpic gfg_wrap.c gfg.c -I / use / include / python2.7 

Sostituisci python2 .7 con la tua versione di Python. Questo creerà due file oggetto
"Gfg_wrap.o‚" e "gfg.o‚" . Nel comando sopra —

  • genera codice indipendente dalla posizione (PIC) adatto per l`uso nella libreria condivisa se supportato per la macchina di destinazione. Questo codice accede a tutti gli indirizzi permanenti tramite la Global Offset Table (GOT)

Nota: se ricevi un messaggio di errore come le seguenti possibili cause —

  • Potresti non avere il ' Python.h ' oppure
  • Stai inserendo la posizione sbagliata per il ' Python.h ' per il compilatore

Per ottenere ' Python.h ' devi installare Python-dev, usando il seguente comando —

$ sudo apt-get install python-dev 

Per trovare il percorso corretto di Python.h, esegui il seguente comando —

$ python -config --cflags 

Questo produrrà qualcosa del genere —

Ora sostituisci il percorso nel comando compile con questo per python2.7 o cambia la versione in python3.5 per Python 3.5 .

Ora, finalmente, dobbiamo collegare insieme i file oggetto generati per creare un oggetto condiviso, che è simile ai file DLL su Windows. Usa il comando seguente, questo genererà un file oggetto condiviso "_gfg.so"

$ gcc -shared gfg.o gfg_wrap.o -o _gfg.so 

Ora siamo pronti per testare la shell Python importandola. Assicurati di essere nella directory con questo file di shell.

> > > importa gfg > > > res = fatto (5) > > > ris 120 > > > res = my_mod (5,2) > > > ris 1 > > > gfg.cvar.myvar 3.4 

Qui le variabili C sono disponibili come.

Compilazione e collegamento usando distutils

< / p>

Invece di digitare comandi e capire quali opzioni di compilazione sono necessarie per compilare i file, possiamo automatizzarlo con distutils. Crea come mostrato di seguito —


# File: setup.py


da distutils.core import configurazione, estensione

# nome del modulo

name = "gfg"


# versione del modulo

versione = "1.0"


# specifica il nome dell`estensione e i file di origine
# richiesto per la compilazione

ext_modules = Estensione (nome = `_gfg` , sorgenti = [ " gfg.i " , " gfg.c " ] )


setup (nome = nome,

versione = versione,

ext_modules = [ext_modules])

Ora scrivi i seguenti comandi per compilare e installare il modulo —

$ python setup.py build_ext --inplace 

Dovrebbe apparire come do qualcosa del genere sul terminale —

Possibili alternative

Ovviamente, SWIG — non è l`unico modo per creare wrapper, le seguenti alternative potrebbero essere considerate in base ai loro requisiti —

Nel prossimo nell`articolo vedremo come eseguire il wrapping del codice C++ (OPP)

Link

Questo articolo per gentile concessione di Atul Kumar < /forte> . Se sei come Python.Engineering e desideri contribuire, puoi anche scrivere un articolo utilizzando contribuire.python.engineering o pubblicando un articolo contribuire @ python.engineering.Guarda il mio articolo che appare sulla homepage di Python.Engineering e aiuta altri fanatici.

Per favore posta commenti se trovi qualcosa che non va o se desideri condividere maggiori informazioni sull`argomento discusso sopra.

Shop

Learn programming in R: courses

$

Best Python online courses for 2022

$

Best laptop for Fortnite

$

Best laptop for Excel

$

Best laptop for Solidworks

$

Best laptop for Roblox

$

Best computer for crypto mining

$

Best laptop for Sims 4

$

Latest questions

NUMPYNUMPY

psycopg2: insert multiple rows with one query

12 answers

NUMPYNUMPY

How to convert Nonetype to int or string?

12 answers

NUMPYNUMPY

How to specify multiple return types using type-hints

12 answers

NUMPYNUMPY

Javascript Error: IPython is not defined in JupyterLab

12 answers


Wiki

Python OpenCV | cv2.putText () method

numpy.arctan2 () in Python

Python | os.path.realpath () method

Python OpenCV | cv2.circle () method

Python OpenCV cv2.cvtColor () method

Python - Move item to the end of the list

time.perf_counter () function in Python

Check if one list is a subset of another in Python

Python os.path.join () method