Sådan integreres Python kode i C-program

Python er et af de mest populære programmeringssprog på grund af sin enkle syntaks, nem læring og platformsupport. Desuden er der mange tilgængelige Python biblioteker og moduler af høj kvalitet til rådighed, så du kan gøre tunge løft med kun få linjer kode. Dette gør Python til en af ​​de mest produktive måder at udvikle prototyper på. Python er imidlertid ikke så hurtig som C-programmeringssprog, og mange ydeevne-kritiske produktionssoftware som Linux-operativsystemet, webservere og databaser er skrevet i C. Hvis du udvikler et program i C, men en del af det behøver at blive skrevet i Python, kan du skrive et Python-modul til det og indlejre Python-modulet i et C-program ved hjælp af Python / C API.

I denne vejledning skal vi undersøge, hvordan du bruger Python / C API til at indlejre Python-kode i C. Tutorialen afsluttes med et komplet eksempel på at kalde Python fra C-kode.

Trin 1: Installer Python Development Package

Som du har brug for at få adgang til Python / C API, skal du først installere Python udviklingspakke.

På Debian, Ubuntu eller Linux Mint:

$ sudo apt-get install python2.7-dev

På CentOS, Fedora eller RHEL:

$ sudo yum installer python-devel

Når installationen er vellykket, vil Python header filen findes i / usr / include / python2.7. Afhængig af din Linux-distribution kan den nøjagtige sti være anderledes. For eksempel er det / usr / include / python2.6 på CentOS 6.

Trin 2: Initialiser tolk og indstillet sti

Det første skridt i retning af indlejring af Python i C er at initialisere Python-tolk, som kan gøres med følgende C-funktion.

Py_Initialize ();

Når tolken er initialiseret, skal du indstille stien til Python-modulet, du gerne vil importere i dit C-program. Lad os f.eks. Sige, at dit Python-modul er placeret i / usr / local / modules. Brug derefter følgende C-funktionsopkald til at indstille stien.

PySys_SetPath ( "/ usr / local / moduler");

Trin 3: Datakonvertering

Et af de vigtigste aspekter ved indlejring af Python i C er datakonvertering. For at videregive data til en Python-funktion fra C, skal du først konvertere dataene fra C-datatyper til Python-datatyper. Python / C API tilbyder forskellige funktioner til at opnå dette. For at konvertere C-streng til Python-streng bruger vi PyString_FromString () -funktionen:

PyObject * pval; char * cString = "Cyberpersons"; pval = PyString_FromString (cString);

En anden lignende funktion er PyInt_FromLong (), som konverterer lang datatype i C til Python int. Hver Python / C API-funktion returnerer en reference af PyObject-typen.

Trin 4: Definer en Python-modul

Når du vil indlejre Python-kode på et andet sprog som C, skal koden skrives i et Python-modul, som derefter "importeres" på et andet sprog. Så lad os undersøge, hvordan du importerer et Python-modul i C.

Til illustration, lad os implementere et simpelt eksempel Python-modul som følger.

def printData (data): return data + data + 'n'

Ovenstående Python-funktion tager en streng som et argument og returnerer to gentagelser af strengen. Hvis f.eks. Indtastningsstreng er "cyberpersons", returnerer denne funktion "cyberpersonscyberpersons." Navngiv denne modulfil som "printData.py" og læg modulet i Python-modulkataloget angivet tidligere (/ usr / local / modules).

Trin 5: Indlæs en Python-modul

Nu hvor du har defineret dit Python-modul, er det tid til at indlæse det i et C-program. C-koden til import af modulet ser sådan ud:

// argv [1] specificerer modulfilnavnet ("printData.py"). pName = PyString_FromString (argv [1]); pModule = PyImport_Import (pName);

Trin 6: Konstruer funktionsargumenter

Når du har indlæst et modul, er du klar til at kalde Python-funktioner defineret i modulet. Vi skal typisk passere en eller flere argumenter til en Python-funktion. Vi skal konstruere et Python tuple objekt, der indeholder argumenterne for en Python funktion.

I vores eksempel tager printData () -funktionen defineret i vores modul et argument. Således konstruerer vi et Python tuple objekt med størrelse en som følger. Vi kan sætte hvert element i tuple-objektet ved hjælp af PyTuple_SetItem ().

PyObject * pythonArgument; pythonArgument = PyTuple_New (1); pValue = PyString_FromString (argv [3]); if (pValue == NULL) {return 1; } PyTuple_SetItem (pythonArgument, 0, pValue);

Vi har succesfuldt konstrueret et argument, der skal sendes langs funktionsopkaldet, den tid vi skal kalde pythonfunktionen fra vores C-applikation.

Trin 7: Kald en Python-funktion

Når et Python-tuple-objekt er blevet oprettet som funktionsargumenter, kan vi kalde en Python-funktion, der tager argumenterne. Til dette skal du først hente referencen til funktionen defineret i et modul ved at bruge PyObject_GetAttrString (), og derefter kalde funktionen med PyObject_CallObject (). For eksempel:

// argv [2] er det funktionsnavn, der er defineret i pModule // pFunc er henvisningen til funktionen pFunc = PyObject_GetAttrString (pModule, argv [2]); pValue = PyObject_CallObject (pFunc, pythonArgument);

Trin 8: Fejlkontrol

En fælles måde at undgå run-time-fejl på er at kontrollere returværdien af ​​en funktion og træffe passende handlinger afhængigt af returværdien. I lighed med errno global variabel i C-programmer opretholder Python / C API en global indikator, der rapporterer om den sidste fejl, der opstod. Når en Python / C API-funktion mislykkes, er den globale indikator indstillet til at angive fejlen, og PyErr_Print () kan bruges til at vise en tilsvarende menneskelig læsbar trackback. For eksempel:

pModule = PyImport_Import (pName); if (pModule! = NULL) {// Gør noget nyttigt her} ellers {PyErr_Print (); // print traceback fprintf (stderr, "Kunne ikke indlæse"% s "n", argv [1]); return 1; }

Du kan nemt inkorporere forskellige fejlkontroller i dine applikationer.

Her er det komplette C-program, der indgår Python-kode som beskrevet i denne vejledning.

// afhængigt af distros kan den nøjagtige sti eller Python-version variere. #include </usr/include/python2.7/Python.h> #include <stdlib.h> #include <string.h> int main (int argc, char * argv []) {PyObject * pName, * pModule, * pDict , * pFunc; PyObject * pArgs, * pValue; Py_Initialize (); PySys_SetPath ( "/ usr / local / moduler"); // sti til modulet, der skal importeres pName = PyString_FromString (argv [1]); pModule = PyImport_Import (pName); if (pModule! = NULL) {PyObject * pythonArgument; pythonArgument = PyTuple_New (1); pValue = PyString_FromString (argv [3]); if (pValue == NULL) {return 1; } PyTuple_SetItem (pythonArgument, 0, pValue); pFunc = PyObject_GetAttrString (pModule, argv [2]); if (pFunc && PyCallable_Check (pFunc)) {pValue = PyObject_CallObject (pFunc, pythonArgument); if (pValue! = NULL) {printf ("Værdi retur fra funktionen% s", PyString_AsString (pValue)); } andet {PyErr_Print (); }} andet {if (PyErr_Occurred ()) PyErr_Print (); fprintf (stderr, "Kan ikke finde funktion"% s "n", argv [2]); }} andet {PyErr_Print (); fprintf (stderr, "Kunne ikke indlæse"% s "n", argv [1]); return 1; }}

Trin 9: Kompilér og udfør

Gem ovennævnte kode som finalCode.c, og kompilér koden, mens du linker til Python-biblioteket (-lpython2.7). Afhængig af distros kan du bruge forskellige versioner (f.eks. -lpython2.6).

$ gcc -o endelige finalCode.c-lpython2.7

Kør nu den kompilerede eksekverbare med tre argumenter:

./final printData printData cyberpersons

De tre argumenter i denne eksamen er modulnavnet, funktionsnavnet i modulet, strengen argumentet, der skal overføres til Python-funktionen.

Din produktion vil være sådan noget:

Håber dette hjælper.

Kilde

Giv en kommentar

Dette websted bruger Akismet til at reducere spam. Lær, hvordan dine kommentardata behandles.