Išplė&mas. Esamo funkcionalumo papildymas naujomis galimybėmis

Similar documents
Extending and Embedding Python

Extending and Embedding the Python Interpreter

Extending and Embedding Python

C programavimo kalba. 3 paskaita (Sąlygos ir ciklo operatoriai, funkcija scanf() )

SCRIPTING I/III EXTENDING PYTHON. References:

JAVA pagrindai Lek. Liudas Drejeris

Kas yra masyvas? Skaičių masyvo A reikšmės: Elementų indeksai (numeriai): Užrašymas Turbo Paskaliu: A[1] A[2] A[3] A[4] A[5]

C programavimo kalba. 5 paskaita (Funkcijos, masyvai)

Struktūrų sintaksė Struktūra tai vienodo arba skirtingo tipo kintamųjų rinkinys. Sintaksė: struct vardas { ; type1 var1; type2 var2;... typen varn; //

Parengė ITMM Artūras Šakalys 1

C++ programavimo kalba. Konstruktorius, destruktorius, klasių metodų modifikatoriai, objektų masyvai (4 paskaita)

Kodėl programą sudaro daug failų? Sukurtos tipinės funkcijų galėtų būti panaudojamos dar kartą; Sudaroma aiškesnė programos struktūra; Sudaroma galimy

Buferio perpildymo klaida Įvadas, techniniai klausimai

PHP PROGRAMOS EIGOS VYKDYMO VALDYMAS

Come to the TypeScript

Gijos. Gijų modelis Javoje. R.Vaicekauskas, OP, 2017

PYTHON IS SLOW. Make it faster with C. Ben Shaw

C - extensions. only a small part of application benefits from compiled code

C++ programavimo kalba

Extending and Embedding the Python Interpreter

C++ programavimo kalba

Elektroninis.lt šakninių sertifikatų diegimas

El. pašto konfigūravimas

Apletai (įskiepiai) Lekt. dr. Pijus Kasparaitis m. m. pavasario semestras.

Polimorfizmas. Lekt. dr. Pijus Kasparaitis m. m. pavasario semestras.

Python Optimization and Integration

2017 m. pagrindinės sesijos informacinių technologijų valstybinio brandos egzamino programavimo užduoties galimi sprendimai

Informacijos apsaugos standartai serija

Projektas. .h failai Header failai (interface) .m failai Pačios programos failai ( .xib /.storyboard Vartotojo sąsajos failai

Paskirstytos atminties lygiagretusis programavimas Įvadas į MPI

Web servisai WSDL. Osvaldas Grigas

C++ programavimo kalba

C++ programavimo kalba

Amadeus On-Line Helpdesk

K R I S T I N A L A P I N. I dalis. Matematikos ir statistikos studijų krypčių pirmo kurso studentams

KRISTINA LAPIN PROGRAMAVIMAS PASKALIU IR C. II dalis MATEMATIKOS IR STATISTIKOS STUDIJŲ KRYPČIŲ PIRMO KURSO STUDENTAMS

Simboliai ir simbolių eilutės 2 val. Standartinės procedūros ir funkcijos darbui su simbolių eilutėmis

Python/C API Reference Manual

The Python/C API. Release Guido van Rossum Fred L. Drake, Jr., editor. January 04, Python Software Foundation

PHP Lietuviškai. Turinys

C++ programavimo kalba

Pažintis su C++ Builder

Programavimas C kalba

C programos struktūra ir funkcijos

An Introduction to Programming in Python. Stephen White

ios Uždara operacinė sistema skirta tik Apple įrenginiams: iphone ipad ipod touch Apple TV

Vilniaus universitetas Fizikos fakultetas Radiofizikos katedra R. Grigalaitis Programavimas (Programavimo C++ kalba paskaitų konspektas)

ĮVADAS JVM Java Virtual Machine Java virtualios mašinos (JVM) JVM write once, run everywhere

double *pdouble1, *pdouble2, *pdouble3, double4;

Paveikslėliai. Lekt. dr. Pijus Kasparaitis m. m. pavasario semestras.

Embedding Python in Your C Programs

Trumpai-ilga istorija

II SEKCIJA. Duomenų bazės ir modeliai

Programinio kodo saugumas

Interaktyviame režime: visi 5 etapai vykdomi nuosekliai; DBVS SQL sakinius interpretuoja. Programose: dalis etap gali bti atlikti kompiliuojant.

Weather Visualizing Cloud Lamp

Register your product and get support at SHB9100. LT Vartotojo vadovas

HTML dokumentai. Praktinės užduotys

16. ŠABLONAI. int abs( int ); float fabs( float ); double dabs( double ),...

KAUNO TECHNOLOGIJOS UNIVERSITETAS

Naujos galimybės su Lotus Notes 8.5.1: naudotojams ir programuotojams

Interneto technologijų taikymai

1. AJAX įvadas. AJAX principai:

6-7-8 PASKAITOS. Bendros žinios

2-3 PASKAITOS. Paprasčiausia programa:

Objektiškai Orientuotas Programavimas su C++

A Lithuanian Verbalization Template for ORM conceptual models and rules

C++ programavimo kalba

The Python/C API Release Guido van Rossum and the Python development team

A.Kynienė. С, C++ kalbų ABC. Metodinė priemonė

DTD aprašas gali būti XML failo viduje. Šiuo atveju jis įterpiamas į žymę DOCTYPE naudojant tokią sintaksę:

ŠIAULIŲ UNIVERSITETAS MATEMATIKOS IR INFORMATIKOS FAKULTETAS INFORMATIKOS KATEDRA. Mindaugas Gapšys BAKALAURO DARBAS

Paprastų lentelių kūrimas

C++ programavimo kalba

Masyvai Javoje. Masyvai. Objektų talpyklos. Masyvo tipas. Deklaravimo pavyzdžiai. Deklaracija ir sukūrimas. Masyvo superklas - Object

Collections (Java) Collections Framework

Alien GOO a Lightweight C Embedding Facility. Jonathan Bachrach MIT CSAIL. Alien MIT 1 19DEC03


Uždavinių sprendimas MATLAB aplinkoje

4 SKYRIUS. Programuojamieji loginiai valdikliai. Įvadas

Redis Ma as, greitas, galingas. Specialiai VilniusPHP

WWW aplikacijų saugumas 2

Duomenų vietisumo užtikrinimas

Web technologijos. Hostingas JavaScript PHP

Tautvydas Dagys Microsoft Lietuva

TIES VMI duomenų mainų posistemis. Duomenų teikimo sąsajos aprašas

T u r b o P a s k a l i s 7.0

CS 3113 Introduction to Operating Systems Midterm October 11, 2018

CS 3113 Introduction to Operating Systems Midterm October 11, 2018

Objektinis programavimas su C++ naudojant Qt 4

Cython. April 2008 Brian Blais

LOGINĖS DB SCHEMOS ATSTATYMAS NAUDOJANT JDBC

KLIENTŲ DUOMENŲ BAZĖS IR SANTYKIO SU KLIENTAIS VALDYMO PROGRAMA

HTML dokumentai aprašo tinklalapius. HTML dokumentus sudaro HTML gairės ir grynas tekstas. HTML dokumentai vadinami tinklalapiais.

Step-by step guide for MRU students to uploading Master s Thesis to elaba repository

Vienlusčių įtaisų projektavimas. 1 paskaita

Windows saugumo požiūriu

ELEKTRONINIŲ PROJEKTŲ RENGIMO IR VALDYMO SISTEMA

Asta Čitavičienė LIBRARY

KOMPIUTERIŲ TINKLAI. 5 paskaita Tinklo lygmuo, IP protokolas

Transcription:

Išplė&mas Esamo funkcionalumo papildymas naujomis galimybėmis

Kam to reikia? Realizuoti naujus įtaisytuosius (built- in) objektų tipus Iškviesti C bibliotekų funkcijas ir sisteminius kvietimus

Ko reikia? Reikalingas Python API: Funkcijos Makrokomandos Kintamieji Python.h

Paprastas pavyzdys >>> import spam >>> status = spam.system("ls - l")

#include <Python.h> // Čia turėtų būti norima C funkcija //Funkcijos API static PyObject * spam_system(pyobject *self, PyObject *args){ const char *command; int sts; if (!PyArg_ParseTuple(args, "s", &command)) return NULL; sts = system(command); if (sts < 0) { //PyErr_SetString(spamError, "System command failed"); return NULL; } return Py_BuildValue("i", sts); }

Paaiškinimai (I) Vyksta tiesioginis reikšmių iš Python o į C vertimas. C funkcija visada turi du kintamuosius self ir args self naudojamas realizuojant įtaisytuosius metodus, bet ne funkcijas args yra rodyklė į Python o kortežą (tuple), saugantį argumentus, kur kiekvienas elementas atitinka argumentą vertimo funkcijos argumentų sąrašę. Vertimą atlieka funkcija PyArg_ParseTuple()

Paaiškinimai (II) PyArg_ParseTuple grąžina True, jei visi argumentai turi atitinkamą tipą ir būna išsaugoti kintamųjų, kurių adresai perduoti grąžina False, jei perduotas neteisingas argumentų sąrašas Grąžinamas NULL yra klaidos požymis!!! sts yra funkcijos kvietimo rezultatas, bet jį reikia paversti Python o objektų

Paaiškinimai (III) Py_BuildValue(tipas, reikšmė) funkcija, verčianti rezultatą į objektą. Reikia nurodyti kokio tipo reikšmė bus verčiama. Jeigu funkcija yra void tipo, tuomet ji vistiek turi grąžinti Python o atitikmenį None Py_None

Metodų lentelė static PyMethodDef spammethods[] = { {"system", spam_system, METH_VARARGS, "Execute a shell command."}, {NULL, NULL, 0, NULL} /* Sentinel */ };

Paaiškinimai 1 parametras vardas 2 parametras funkcijos API vardas 3 parametras požymis (flag); visada turėtų būti METH_VARARGS [ METH_KEYWORDS]; 0 reiškia pasenusios (obsolete) funkcijos PyArg_ParseTuple naudojimą Jei naudojami vardiniai argumentai, tuomet reikalingas METH_KEYWORDS požymis ir PyArg_ParseTupleAndKeywords() funkcija

Inicializavimas Python 2 Python 3 PyMODINIT_FUNC initspam (void){ (void) Py_InitModule ("spam", spammethods); } static struct PyModuleDef spammodule = { PyModuleDef_HEAD_INIT, "spam", // name of module NULL, // module documentation - 1, // size of per- interpreter state spammethods }; PyMODINIT_FUNC PyInit_spam (void){ return PyModule_Create (&spammodule); }

Paaiškinimai Python 2 atveju initname() yra inicializuojanti funkcija, kur name yra modulio vardas Py_InitModule(modulio_vardas, metodų_lentelė) Python 3 atveju reikia apsirašyti modulio struktūrą ir tik tada inicializuojamas modulis PyInit_name, kur name yra modulio vardas PyModule_Create(modulio_struktūra)

Kompiliavimas distutils paprastas įrankis, trūksta funkcionalumo setuptools iš esmės išplečia distutils apribojimus distribute sujungtas su setuptools distutils2 apleistas projektas distlib - vystomas? bento turėtų pakeisti ankstesnius įrankius. Vystomas?

setup.py from distutils.core import setup, Extension module1 = Extension( demo, sources = [ demo.c ]) setup (name = PackageName, version = 1.0, description = This is a demo package, ext_modules = [module1])

Pavyzdys from distutils.core import setup from distutils.core import Extension MOD = "spam" module = Extension(MOD, sources = ["spammodule.c"]) setup(name = MOD, ext_modules = [module])

Baigiant python3 setup.py build python3 setup.py install python3 setup.py install - - user

Reikšmių ver&mas į C Reikšmės verčiamos į C dviejų funkcijų pagalba: PyArg_ParseTuple(PyObject *arg, char *format,...) PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict, char *format, char *kwlist[],...)

PyArg_ParseTuple(PyObject *arg, char *format,...) Kadangi verčiamas objektas, tai jo struktūra gali būti sudėtinga, bet ją galima apsirašyti *format pagalba s simbolių eilutė (ii)s# dviejų sveikųjų skaičių kortežas ir simbolių eilutė su jos ilgiu s si simbolių eilutė ir galimi papildomai antra simbolių eilutė ir sveikasis skaičius

PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict, char *format, char *kwlist[],...) arg argumentai kwdict vardiniai argumentai format formatavimas kwlist vardinių argumentų vardų sąrašas int voltage; char *state; static char *kwlist[] = { voltage, state, NULL} PyArg_ParseTupleAndKeywords(args, keywds, i s, kwlist, &voltage, &state)

Reikšmių ver&mas į Python ą PyObject *Py_BuildValue(char *format,...) None i sveikas skaičius (ii) dviejų sveikųjų skaičių kortežas s# simbolių eilutė ir ją sudarančių simbolių skaičius [i,i] dviejų sveikųjų skaičių sąrašas {s:i, s:i} - žodynas

Rodyklių skaičiavimas (reference count) Metodika skirta atminties nutekėjimo (memory leak) valdymui Kiekvienas objektas turi skaitliuką, kuris padidinamas, kai yra išsaugoma rodyklė į objektą, ir sumažinamas, kai rodyklė ištrinama.

Py_INCREF, Py_DECREF Makrosai, atsakingi už objekto rodyklių skaitliukų valdymą Egzistuoja analogiški makrosai Py_XINCREF ir Py_XDECREF Patikrina NULL rodyklių egzistavimą

NULL problema Funkcijų argumentai neturėtų būti NULL Funkcijos rezultatas neturėtų būti NULL NULL suprantamas kaip įvykusi klaida Priešingu atveju reikėtų rašyti daug perteklinio kodo NULL rodyklėms suvaldyti

Klaidos ir išimtys Išimtys saugomos statinio globalaus kintamojo interpretatoriaus viduje, jei jis yra NULL, išimtis neįvykusi Antrasis globalus kintamasis saugo išimties susijusią reikšmę Trečiasis kintamasis saugo steko pėdsaką (stack traceback) Šie trys kintamieji yra C kalbos ekvivalentas Python o kintamiesiems sys.exc_type, sys.exc_value, sys.exc_traceback

Klaidų funkcijos PyErr_SetString(exception_object, string) Išimties objektas paprastai būna iš anksto apibrėžtas objektas kaip PyExc_ZeroDivisionError Simbolių eilutė aprašo klaidos priežastį PyErr_SetFromErrno(exception_argument) PyErr_SetObject(exception, value) bendriausia funkcija PyErr_Occured() leidžia patikrintiar įvyko klaida klaidos objektas arba NULL

Klaidų mechanizmas Jei funkcija f kviečia funkciją g ir pastaroji grąžino klaidą, funkcija f taip pat turėtų grąžinti klaidos reikšmę (NULL arba - 1) PyErr_* funkcijų tokiu atveju kviesti papildomai nebereikia Gali pasitaikyti atvejų, kuomet tai vis dėlto daroma tam, kad tiksliau aprašyti klaidą PyErr_Clear() išvalo klaidą jos neperduodant interpretatoriui

Nauja klaida Galima sukurti naują klaidą (Python 2 kodas): static PyObject *spamerror; initspam(void){ PyObject *m; spamerror = PyErr_NewException("spam.error", NULL, NULL); Py_INCREF(spamError); PyModule_AddObject(m, "error", spamerror); }

Nauja klaida Galima sukurti naują klaidą (Python 3 kodas): static PyObject *spamerror; PyMODINIT_FUNC PyInit_spam(void){ PyObject *m=pymodule_create(&spammodule); spamerror = PyErr_NewException("spam.error", NULL, NULL); Py_INCREF(spamError); PyModule_AddObject(m, "error", spamerror); }

Naujo &po apibrėžimas Python o interpretatorius mato visus objektus kaip PyObject PyObject saugo rodyklės skaitliuką ir rodyklę į objekto tipą ( type object ) Tipas apibrėžia kokios funkcijos (dar vadinamos tipo metodais) yra kviečiamos

Tipas typedef struct{ PyObject_HEAD /* Type-specific fields go here. */ } noddy_noddyobjec t; PyObject_HEAD makrosas, kuris užtikrina rodyklės skaitliuko ir rodyklės įtraukimą Kabliataškis nededamas!

Objektas static PyTypeObject noddy_noddytype ={ PyVarObject_HEAD_INIT(NULL, 0) "noddy.noddy", /*tp_name*/ sizeof(noddy_noddyobject), / *tp_basicsize*/ 0, /*tp_itemsize*/ 0, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_reserved*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ "Noddy objects", /* tp_doc */ }; PyTypeObject C įrašo tipas, aprašantis įtaisytuosius tipus Laukų yra daugiau, tačiau paprastai jie paliekami užpildyti kompiliatoriui Kiekvienas iš šiuo metu neaprašytų laukų turi savo paskirtį, pavyzdžiui, tp_itemsize reikalingas kintamo dydžio objektams

Modulis static struct PyModuleDef noddymodule ={ PyModuleDef_HEAD_INIT, "noddy", // name of module "Example of new type", // module documentation, may be NULL -1, // size of perinterpreter state of the module, or -1 if the module keeps state in global variables. NULL, NULL, NULL, NULL, NULL}; Modulio aprašymas

PyType_GenericNew PyMODINIT_FUNC PyInit_noddy(void) { PyObject* m; noddy_noddytype.tp _new = PyType_GenericNew; if (PyType_Ready (&noddy_noddytype) < 0) return NULL; PyType_GenericNew bendroji funkcija (generic handler), sukurianti naują objektą (atminties išskyrimas) PyType_Ready() inicializuoja tipą

Užbaigiant modulį m = PyModule_Create (&noddymodule); if (m == NULL) return NULL; Py_INCREF (&noddy_noddytype); PyModule_AddObject (m, "Noddy", (PyObject *)&noddy_noddytype); return m;} PyModule_AddObject() įtraukia tipą į modulio žodyną

Suteikiant funkcionalumo Įrašo tipą galima papildyti norimais laukais Aprašomos funkcijos objektui sukurti (pvz. new, init ir t.t.) ar sunaikinti ir valdyti (pvz. set, get), taip pat metodai Užpildoma laukų lentelė PyMemberDef Užpildoma valdymo funkcijų lentelė PyGetSetDef Užpildoma metodų lentelė PyMethodDef Aprašomas objektas PyTypeObject, nurodant metodus ir lenteles Užpildomas modulio aprašas ir aprašoma modulio inicializavimo funkcija

Įterpimas Duomenų konvertavimas iš C į Python ą Kviečiama Python o sąsaja Duomenų konvertavimas iš Python o į C

#include <Python.h>! int main(int argc, char *argv[]){! Py_Initialize();! PyRun_SimpleString("from time import time,ctime\n"! "print('today is', ctime(time()))\n");! Py_Finalize();! return 0;! } Pats paprasčiausias būdas įterpti Python o kodą: Inicializuojame Python o interpretatorių Įvykdome kodą Užbaigiame darbą su interpretatorium

Sudė&ngesnis pavyzdys #include <Python.h>! int main(int argc, char *argv[]){! PyObject *pname, *pmodule, *pdict, *pfunc;! PyObject *pargs, *pvalue;! int i;! if (argc < 3) {! fprintf(stderr,"usage: call pythonfile funcname [args]\n");! return 1;! }! Standartinė pradžia. Patikriname ar pakaks parametrų.

Pradedame darbą Py_Initialize(); pname = PyString_FromString(argv[1]); PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.insert(0, '')"); pmodule = PyImport_Import(pName); Py_DECREF(pName); Pirmasis programos parametras paverčiamas objektu, tai bus Python o failo (modulio) vardas Nustatome, kad darbinis Python o katalogas būtų dabartinis katalogas, kuriame yra failas Importuojame failą kaip modulį

Judame toliau if (pmodule!= NULL) { pfunc = PyObject_GetAttrString (pmodule, argv[2]); /* pfunc is a new reference */ if (pfunc && PyCallable_Check (pfunc)) { pargs = PyTuple_New(argc - 3); Jei su moduliu viskas gerai, iš jo pasiimame funkciją, kurios vardas yra antrasis programos parametras Jei su funkcija viskas gerai, konstruojame kortežą parametrams

Parametrai, parametrai... for (i = 0; i < argc - 3; ++i) { pvalue = PyInt_FromLong(atoi(argv[i + 3])); if (!pvalue) { Py_DECREF(pArgs); Py_DECREF(pModule); fprintf(stderr, "Cannot convert argument\n"); return 1; } /* pvalue reference stolen here: */ PyTuple_SetItem(pArgs, i, pvalue); } Nuskaitome funkcijos parametrus iš programos parametrų ir juos konvertuojame į Python o tipus Jei konvertavimas pavyko, įdedame reikšmę į kortežą

Funkcijos kvie&mas pvalue = PyObject_CallObject(pFunc, pargs); Py_DECREF(pArgs); if (pvalue!= NULL) { printf("result of call: %ld\n, PyInt_AsLong(pValue)); Py_DECREF(pValue); } else { Py_DECREF(pFunc); Py_DECREF(pModule); PyErr_Print(); fprintf(stderr,"call failed\n"); return 1; } } Kviečiame funkciją jai perduodami paramtrus Jei funkcija sėkmingai įvykdyta, rezultatą spausdiname kaip C reikšmę (long) Jei blogai spausdinamas klaidos pranešimas

Pabaiga else { if (PyErr_Occurred()) PyErr_Print(); fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]); } Py_XDECREF(pFunc); Py_DECREF(pModule); } else { PyErr_Print(); fprintf(stderr, "Failed to load \"%s \"\n", argv[1]); return 1; } Py_Finalize(); return 0; } Sutvarkome likusias klaidas

Failas Dešinėje matoma reikalinga funkcija Funkcija turėtų būti patalpinta faile multiply.py, nors tiktų bet koks pavadinimas Šis failas ir programos c kodas turėtų btūi viename kataloge def multiply(a, b): print ("Will compute", a, "times", b) c = 0 for i in range(0, a): c = c + b return c

Kompiliavimas Norint sukompiliuoti įterptinį kodą, reikia kompiliatoriui nurodyti papildomas instrukcijas Kokias žymes naudoti compiliuojant, galima sužinoti komandos python3- config cflags pagalba Kokias žymes naudojant susiejant (linking), galima sužinoti komandos python3- config ldflags pagalba Pavyzdys (MIF linux klasėse): gcc - I/usr/include/python3.4m embed.c - lpython3.4m

Pagaliau! $./a.out multiply multiply 3 2 Will compute 3 times 2 Result of call: 6 Kviečiame sukompiliuotą programą Vykdymo rezultatas