Pakowanie C/C++ dla Pythona przy użyciu SWIG — Zestaw 1

| | | | | | | | | | |

Nie ma wątpliwości, że Numpy, wykonuje ogromną ilość zadania ? W rzeczywistości biblioteki takie jak Numpy nie są napisane w całości w Pythonie, niektóre części biblioteki są napisane w C, co zapewnia lepszą wydajność. Po napisaniu kodu C owijamy go kodem Pythona, który działa jako interfejs dla tych kodów C. Następnie możemy wywoływać funkcje C przy użyciu składni Pythona, gdzie faktyczne przetwarzanie odbywa się w C w tle, a wynik jest zwracany jako obiekt Pythona. W tym artykule zobaczymy, jak utworzyć opakowanie Pythona dla naszego programu w języku C w systemach Linux przy użyciu oprogramowania SWIG .

Co to jest SWIG

W skrócie SWIG — jest to kompilator, który akceptuje deklaracje C / C++ i opakowuje go, aby uzyskać dostęp do tych deklaracji z innych języków, takich jak Python, Tcl, Ruby itp.
Zazwyczaj nie wymaga to żadnych zmian w istniejącym kodzie i tworzy interfejs w ciągu minuty.

Powody tworzenia opakowania

W wielu przypadkach potrzebujemy opakowań, następujące: —

  • Budowanie zinterpretowanego interfejsu dla istniejących programów C.
  • Tworzenie wysokowydajnych modułów C dla języków skryptowych ‚Ę‚‚
  • Testowanie dużych programów C jest bardzo trudne, dlatego piszemy wrappery w niektórych językach skryptowych ‚‚â‚ bardzo łatwo jest pisać testy. etc

Instalowanie SWIG

Aby pobrać SWIG bezpośrednio z repozytorium apt, wprowadź następujące polecenia —

sudo apt-get update sudo apt-get install swig 

Pisanie wrappera za pomocą SWIG

Przyjrzyjmy się ten fragment kodu w C z dwiema funkcjami i jedną zmienną globalną —


/ * plik: gfg.c * /


# include "stdio.h >
# include "matematyka >


// nasz plik nagłówkowy
# include "gfg.h"
# zdefiniuj ll long long


double myvar = 3.4;


// oblicz silnię

ll int fakt (ll int n)

{

if (n "= 1)

return 1;

else

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

}


// znajdź mod

int my_mod ( int n, int m )

{

return (n% m);

}

Oto nasz plik nagłówkowy — ;


long long int fakt ( long long int n);

int my_mod ( int n, int m);

Najpierw musimy utworzyć plik interfejsu SWIG . Ten plik zawiera prototypy funkcji ANSI C i deklaracje zmiennych. Tutaj —

  • Dyrektywa % module określa nazwę modułu, którego będziemy używać w Pythonie.
  • % {. . % } zapewnia miejsce na wstawienie dodatkowego kodu, takiego jak pliki nagłówkowe C lub dodatkowe deklaracje C, do wygenerowanego kodu opakowania.
  • Dyrektywa % include pozwala nam dołączyć dodatkowe pliki, takie jak pliki nagłówkowe.

/ * plik: gfg.i * /


/ * nazwa używanego modułu * /
% moduł gfg
% {

/ * Wszystko w tym pliku jest kopiowane do

plik opakowania. Dołącz wymagany plik nagłówka C

skompiluj interfejs * /

# include "gfg.h"

/ * deklaracja zmiennej * /

double myvar;

%}


/ * jawna lista funkcji i zmiennych do interakcji * /

double myvar;

long long int fakt ( long long int n1);

int my_mod ( int m, int n);


/ * lub jeśli chcemy połączyć wszystkie funkcje, możemy po prostu

dołącz taki plik nagłówkowy -

% to & quot; gfg.h & quot;

* /

Teraz utworzymy kod opakowania za pomocą polecenia takiego jak

$ swig -python gfg.i 

To polecenie generuje kod opakowania o nazwie "gfg_wrap.c" . Pliki te zawierają nadętą wersję naszego źródła C z innym kodem obsługi błędów itp. Wygenerowano inny plik "gfg.py", będący modułem, który importujemy do naszego skrypt Pythona.


Następnie musimy wygenerować kod niezależny od pozycji do użycia w bibliotece współdzielonej, kompilując "gfg_wrap.c" i "gfg .c" za pomocą następującego polecenia:

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

Zamień python2 .7 z twoją wersją Pythona. Spowoduje to utworzenie dwóch plików obiektowych
"Gfg_wrap.o" i "gfg.o" . W powyższym poleceniu —

  • wygeneruj kod niezależny od pozycji (PIC) odpowiedni do użycia w bibliotece dzielonej, jeśli jest obsługiwany dla maszyny docelowej. Ten kod umożliwia dostęp do wszystkich stałych adresów za pośrednictwem tabeli globalnych przesunięć (GOT)

Uwaga: jeśli pojawi się komunikat o błędzie, taki jak następujące możliwe przyczyny —

  • Możesz nie mieć ' Python.h ' lub
  • Wprowadzasz niewłaściwą lokalizację dla ' Python.h ' dla kompilatora

Aby uzyskać ' Python.h ' musisz zainstalować Python-dev, za pomocą następującego polecenia —

$ sudo apt-get install python-dev 

Aby znaleźć poprawną ścieżkę do Python.h, uruchom następujące polecenie —

$ python -config --cflags 

Spowoduje to wyświetlenie czegoś takiego —

Teraz zastąp ścieżkę w poleceniu kompilacji tą dla python2.7 lub zmień wersję na python3.5 dla Pythona 3.5 .

Teraz, na koniec, musimy połączyć wygenerowane pliki obiektów, aby utworzyć obiekt współdzielony, który jest podobny do plików DLL w systemie Windows. Użyj następującego polecenia, to wygeneruje udostępniony plik obiektu "_gfg.so"

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

Jesteśmy teraz gotowi do przetestowania powłoki Pythona poprzez jej zaimportowanie. Upewnij się, że jesteś w katalogu z tym plikiem powłoki.

> > > importuj gfg > > > res = fakt (5) > > > res 120 > > > res = mój_mod (5,2) > > > res 1 > > > gfg.cvar.myvar 3.4 

Tutaj zmienne C są dostępne jako.

Kompilowanie i łączenie za pomocą distutils

< / p>

Zamiast wpisywać polecenia i zastanawiać się, jakie opcje kompilacji są potrzebne do kompilacji plików, możemy to zautomatyzować za pomocą distutils. Utwórz, jak pokazano poniżej —


# Plik: setup.py


z distutils.core import konfiguracja, rozszerzenie

# nazwa modułu

nazwa = "gfg"


# wersja modułu

wersja = "1.0"


# określ nazwę rozszerzenia i pliki źródłowe
# wymagane do kompilacji

ext_modules = Rozszerzenie (nazwa = ’_gfg’ , źródła = [ " gfg.i " , " gfg.c " ] )


konfiguracja (nazwa = nazwa,

wersja = wersja,

ext_modules = [ext_modules])

Teraz napisz następujące polecenia, aby skompilować i zainstalować moduł —

$ python setup.py build_ext --inplace 

To powinno wyglądać tak coś takiego na terminalu —

Możliwe alternatywy

Oczywiście SWIG — nie jest to jedyny sposób na tworzenie opakowań, poniższe alternatywy można rozważyć w oparciu o ich wymagania —

W następnym artykuł zobaczymy, jak owinąć kod C++ (OPP)

Linki

Ten artykuł dzięki uprzejmości Atul Kumar . Jeśli jesteś Python.Engineering i chcesz wnieść swój wkład, możesz również napisać artykuł, korzystając z Contribute.python.engineering lub publikując artykuł przyczynić @ python.engineering.Zobacz mój artykuł pojawiający się na stronie głównej Python.Engineering i pomóż innym geekom.

Proszę publikować komentarze, jeśli znajdziesz coś nie tak lub jeśli chcesz podzielić się więcej informacjami na omawiany temat powyżej.

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