Empaquetage C/C++ pour Python à l`aide de SWIG — Set 1

| | | | | | | | | | |

Il ne fait aucun doute que Numpy, exécute une énorme quantité de tâches  ? En fait, les bibliothèques comme Numpy ne sont pas entièrement écrites en Python, certaines parties de la bibliothèque sont écrites en C, ce qui offre de meilleures performances. Après avoir écrit le code C, nous les encapsulons dans du code Python, qui agit comme une interface pour ces codes C. Nous pouvons ensuite appeler des fonctions C en utilisant la syntaxe Python, où le traitement réel est effectué en C dans les coulisses, et le résultat est renvoyé sous la forme d`un objet Python. Dans cet article, nous verrons comment créer un wrapper Python pour notre programme C sur des systèmes Linux à l`aide du logiciel SWIG .

Qu`est-ce que SWIG

En un mot, SWIG — c`est un compilateur qui accepte les déclarations C / C++ et les encapsule pour accéder à ces déclarations à partir d`autres langages comme Python, Tcl, Ruby, etc.
Habituellement, cela ne nécessite aucune modification du code existant et crée une interface en une minute.

Raisons pour créer un wrapper

Dans de nombreux cas, nous avons besoin de wrappers, les suivants sont —

  • Construire une interface interprétée pour les programmes C existants.
  • Construire des modules C hautes performances pour les langages de script ‚Äã‚Äã
  • Tester d`énormes programmes C est très difficile, nous écrivons donc des wrappers dans certains langages de script ‚Äã‚Äãcomme Python où il est très facile d`écrire des tests. etc

Installer SWIG

Pour télécharger SWIG directement depuis le référentiel apt, entrez les commandes suivantes —

sudo apt-get update sudo apt-get install swig 

Écrire un Wrapper en utilisant SWIG

Regardons ce bout de code en C avec deux fonctions et une variable globale —


/ * file: gfg.c * /


# inclure "stdio.h >
# inclure "math.h >


// notre fichier d`en-tête
# include "gfg.h"
# définir ll long long


double mavar = 3.4 ;


// calcul factoriel

ll int fact (ll int n)

{/code>

si (n "= 1)

return 1 ;

autre

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

}


// trouve le mod

int mon_mod ( int n, int m )

{

return (n% m);

}

Voici notre fichier d`en-tête — ;


long long int fait ( long long int n);

int mon_mod ( int n, int m);

Nous devons d`abord créer le fichier d`interface SWIG. Ce fichier contient des prototypes de fonctions C ANSI et de déclarations de variables. Ici —

  • La directive % module spécifie le nom du module que nous utiliserons en Python.
  • % {. . % } fournit un emplacement pour insérer du code supplémentaire, tel que des fichiers d`en-tête C ou des déclarations C supplémentaires, dans le code wrapper généré.
  • La directive % include nous permet d`inclure des fichiers supplémentaires tels que des fichiers d`en-tête.

/ * fichier : gfg.i * /


/ * nom du module utilisé * /
% module gfg
% {

/ * Tout ce qui se trouve dans ce fichier est copié dans le

fichier d`emballage. Inclure le fichier d`en-tête C requis

compiler l`interface * /

# inclure "gfg.h"

/ * déclaration de variable * /

double mavar ;

%}


/ * lister explicitement les fonctions et les variables pour l`interaction * /

double myvar;

long long int fait ( long long int n1);

int mon_mod ( int m, int n);


/ * ou si nous voulons lier toutes les fonctions, alors nous pouvons simplement

inclure un fichier d`en-tête comme celui-ci -

% include & quot; gfg.h & quot;

* /

Nous allons maintenant créer le code wrapper en utilisant une commande comme

$ swig -python gfg.i 

Cette commande génère un code wrapper nommé "gfg_wrap.c" . Ces fichiers contiennent une version gonflée de notre source C avec un code de gestion des erreurs différent, etc. Généré un autre fichier "gfg.py", qui est le module que nous importons dans notre script python.


Après cela, nous devons générer du code indépendant de la position à utiliser dans la bibliothèque partagée en compilant "gfg_wrap.c" et "gfg .c" avec la commande suivante :

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

Remplacer python2 .7 avec votre version de Python. Cela créera deux fichiers objets
"Gfg_wrap.o‚" et "gfg.o‚" . Dans la commande ci-dessus —

  • générer un code indépendant de la position (PIC) adapté à une utilisation dans la bibliothèque partagée s`il est pris en charge pour la machine cible. Ce code accède à toutes les adresses permanentes via le Global Offset Table (GOT)

Remarque : si vous recevez un message d`erreur tel que les causes possibles suivantes —

  • Vous n`avez peut-être pas le ' Python.h ' ou
  • Vous saisissez le mauvais emplacement pour le ' Python.h ' pour le compilateur

Pour obtenir ' Python.h ' vous devez installer Python-dev, en utilisant la commande suivante —

$ sudo apt-get install python-dev 

Pour trouver le chemin correct vers Python.h, exécutez la commande suivante —

$ python -config --cflags 

Cela affichera quelque chose comme ceci —

Remplacez maintenant le chemin dans la commande de compilation par celui-ci pour python2.7 ou changez la version en python3.5 pour Python 3.5 .

Maintenant, enfin, nous devons lier les fichiers objets générés pour créer un objet partagé, qui est similaire aux fichiers DLL sous Windows. Utilisez la commande suivante, cela générera un fichier objet partagé "_gfg.so"

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

Nous sommes maintenant prêts à tester le shell Python en l`important. Assurez-vous d`être dans le répertoire contenant ce fichier shell.

> > > importer gfg > > > res = fait (5) > > > res 120 > > > res = my_mod (5,2) > > > res 1 > > > gfg.cvar.myvar 3.4 

Ici les variables C sont disponibles en tant que.

Compilation et liaison à l`aide de distutils

< / p>

Au lieu de taper des commandes et de déterminer quelles options de compilation sont nécessaires pour compiler les fichiers, nous pouvons automatiser cela avec distutils. Créez comme indiqué ci-dessous —


# Fichier : setup.py


de distutils.core import setup, Extension

# nom du module

nom = "gfg"


# version du module

version = "1.0"


# spécifiez le nom de l`extension et les fichiers source
# requis pour la compilation

ext_modules = Extension (nom = `_gfg` , sources = [ " gfg.i " , " gfg.c " ] )


configuration (nom = nom,

version = version,

ext_modules = [ext_modules])

Écrivez maintenant les commandes suivantes pour compiler et installer le module —

$ python setup.py build_ext --inplace 

Cela devrait ressembler à do quelque chose comme ça sur le terminal —

Alternatives possibles

Évidemment, SWIG — ; pas la seule façon de créer des wrappers, les alternatives suivantes pourraient être envisagées en fonction de leurs besoins —

Dans le prochain article, nous verrons comment envelopper du code C++ (OPP)

Liens

Cet article est une gracieuseté de Atul Kumar < /fort> . Si vous êtes Python.Engineering et que vous souhaitez contribuer, vous pouvez également écrire un article en utilisant contribuer.python.engineering ou en publiant un article contribuer @ python.engineering.Voir mon article apparaissant sur la page d`accueil de Python.Engineering et aider d`autres geeks.

Veuillez poster des commentaires si vous trouvez quelque chose de mal ou si vous souhaitez partager plus d`informations sur le sujet abordé ci-dessus.

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