C/C++-verpakking voor Python met SWIG — Stel 1 . in

| | | | | | | | | | |

Het lijdt geen twijfel dat Numpy, voert een enorme hoeveelheid taken ? In feite zijn bibliotheken zoals Numpy niet volledig in Python geschreven, sommige delen van de bibliotheek zijn geschreven in C, wat betere prestaties oplevert. Nadat we de C-code hebben geschreven, verpakken we ze in Python-code, die fungeert als een interface voor die C-codes. We kunnen dan C-functies aanroepen met behulp van de Python-syntaxis, waarbij de daadwerkelijke verwerking achter de schermen in C wordt gedaan en het resultaat wordt teruggestuurd als een Python-object. In dit artikel zullen we zien hoe we een Python-wrapper voor ons C-programma op Linux-systemen kunnen maken met behulp van SWIG -software.

Wat is SWIG

In een notendop, SWIG — het is een compiler die C / C++-declaraties accepteert en deze inpakt om toegang te krijgen tot die declaraties uit andere talen, zoals Python, Tcl, Ruby, enz.
Meestal vereist dit geen wijzigingen in bestaande code en creëert het een interface binnen een minuut.

Redenen voor het maken van een wrapper

In veel gevallen hebben we wrappers nodig, de volgende zijn: —

  • Een geïnterpreteerde interface bouwen voor bestaande C-programma`s.
  • Het bouwen van krachtige C-modules voor scripttalen ‚Äã‚Äã
  • Het testen van enorme C-programma`s is erg moeilijk, dus we schrijven wrappers in sommige scripttalen, zoals Python waar het is heel gemakkelijk om tests te schrijven. etc

SWIG installeren

Om SWIG rechtstreeks uit de apt-repository te downloaden, voert u de volgende opdrachten in: —

sudo apt-get update sudo apt-get install swig 

Een wrapper schrijven met SWIG

Laten we eens kijken naar dit stukje code op C met twee functies en één globale variabele —


/ * file: gfg.c * /


# include "stdio.h >
# include "wiskunde.h >


// ons headerbestand
# include "gfg.h"
# definieer ll long long


double mijnvar = 3.4;


// bereken faculteit

ll int fact (ll int n)

{

if (n "= 1)

return 1;

else

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

}


// vind de mod

int my_mod ( int n, int m )

{

return (n% m);

}

Hier is ons headerbestand — ;


lang lang int feit ( long long int n);

int my_mod ( int n, int m);

Eerst moeten we het SWIG-interfacebestand maken. Dit bestand bevat prototypes van ANSI C-functies en variabele declaraties. Hier —

  • De % module richtlijn specificeert de naam van de module die we in Python zullen gebruiken.
  • % {. . % } biedt een plaats om aanvullende code, zoals C-headerbestanden of aanvullende C-declaraties, in de gegenereerde wrappercode in te voegen.
  • De instructie % include stelt ons in staat om extra bestanden op te nemen, zoals header-bestanden.

/ * bestand: gfg.i * /


/ * naam van de gebruikte module * /
% module gfg
% {

/ * Alles in dit bestand wordt gekopieerd naar de

wrapper-bestand. Voeg het vereiste C-headerbestand toe

compileer de interface * /

# include "gfg.h"

/ * variabele declaratie * /

double myvar;

%}


/ * expliciete lijst van functies en variabelen voor interactie * /

double myvar;

lang lang int feit ( long long int n1);

int my_mod ( int m, int n);


/ * of als we alle functies willen koppelen, dan kunnen we gewoon

inclusief een header-bestand zoals dit -

% include & quot; gfg.h & quot;

* /

Nu gaan we de wrapper-code maken met behulp van een commando als

$ swig -python gfg.i 

Dit commando genereert wrapper-code met de naam "gfg_wrap.c" . Deze bestanden bevatten een opgeblazen versie van onze C-bron met andere foutafhandelingscode, enz. Gegenereerd een ander bestand "gfg.py", dat is de module die we importeren in onze python-script.


Daarna moeten we positie-onafhankelijke code genereren voor gebruik in de gedeelde bibliotheek door "gfg_wrap.c" en "gfg te compileren .c" met het volgende commando:

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

Vervang python2 .7 met uw Python-versie. Hierdoor worden twee objectbestanden
"Gfg_wrap.o‚" en "gfg.o‚" gemaakt. In de bovenstaande opdracht —

  • genereer positie-onafhankelijke code (PIC) die geschikt is voor gebruik in de gedeelde bibliotheek, indien ondersteund voor de doelcomputer. Deze code geeft toegang tot alle permanente adressen via de Global Offset Table (GOT)

Opmerking: als u een foutmelding krijgt zoals de volgende mogelijke oorzaken —

  • Je hebt misschien niet de ' Python.h ' of
  • U voert de verkeerde locatie in voor de ' Python.h ' voor de compiler

Om ' Python.h ' je moet Python-dev installeren met het volgende commando —

$ sudo apt-get install python-dev 

Voer de volgende opdracht uit om het juiste pad naar Python.h te vinden —

$ python -config --cflags 

Dit zal zoiets als dit opleveren —

Vervang nu het pad in het compileercommando door dit pad voor python2.7 of verander de versie naar python3.5 voor Python 3.5 .

Nu moeten we ten slotte de gegenereerde objectbestanden aan elkaar koppelen om een gedeeld object te maken, dat vergelijkbaar is met de DLL -bestanden op Windows. Gebruik de volgende opdracht, dit genereert een gedeeld objectbestand "_gfg.so"

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

We zijn nu klaar om de Python-shell te testen door deze te importeren. Zorg ervoor dat u zich in de map met dit shellbestand bevindt.

> > > import gfg > > > res = feit (5) > > > res 120 > > > res = mijn_mod (5,2) > > > res 1 > > > gfg.cvar.myvar 3.4 

Hier zijn C-variabelen beschikbaar als.

Compileren en koppelen met behulp van distutils

< / p>

In plaats van commando`s te typen en uit te zoeken welke compilatie-opties nodig zijn om bestanden te compileren, kunnen we dit automatiseren met distutils. Maak zoals hieronder getoond —


# Bestand: setup.py


from distutils.core import setup, extensie

# modulenaam

naam = "gfg"


# moduleversie

versie = "1.0"


# specificeer extensienaam en bronbestanden
# vereist voor compilatie

ext_modules = Extensie (naam = `_gfg` , bronnen = [ " gfg.i " , " gfg.c " ] )


setup (naam = naam,

versie = versie,

ext_modules = [ext_modules])

Schrijf nu de volgende opdrachten om de module te compileren en te installeren —

$ python setup.py build_ext --inplace 

Dit zou eruit moeten zien als do zoiets als dit op de terminal —

Mogelijke alternatieven

Het is duidelijk dat SWIG — niet de enige manier om wrappers te maken, de volgende alternatieven kunnen worden overwogen op basis van hun vereisten —

In de volgende artikel zullen we zien hoe u C++ (OPP)-code kunt inpakken

Links

Dit artikel met dank aan Atul Kumar < /sterk> . Als je als Python.Engineering bent en graag een bijdrage wilt leveren, kun je ook een artikel schrijven met Contribut.python.engineering of door een artikel te plaatsen bijdragen @ python.engineering.Zie mijn artikel dat verschijnt op de Python.Engineering-homepage en help andere geeks.

Plaats opmerkingen als je iets verkeerd vindt of als je meer informatie wilt delen over het besproken onderwerp hierboven.

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