Rettentően elmés címem mellett valójában azt szeretném ma leírni, hogy hogyan is kell beépíteni a Pythont illetve a Lua-t saját C++ projectünkbe. Ha eddig nem is lett volna egyértelmű, most már biztos, hogy ez megint egy technikai írás lesz, amit remélem sikerül legalább annyira érdekesre, vagy viccesre megírnom, hogy azért ne aludjon el mindenki a monitor mögött.
LUA
Kezdjük először a Lua val, mivel ez a script áll hozzám közelebb és sokkal jobban is ismerem mint a Pythont, így talán a későbbi botlásokat könnyebben elnézik.
A Lua jelenleg az 5.1 es verziónál tart, C ben fejlesztik és egy eléggé egyedi (már a scriptnyelvek terén) nézőpontot támogat, méghozzá a stack kezelést. Gyanítom ebben rejlik hihetetlen sebességének kulcsa.
A sebességnek viszont mindig ára van, jelen esetben a kicsit sem egyszerű C interface, amivel sajnos meg kell birkóznunk.
#include <stdio.h> #include <stdlib.h> #ifdef __cplusplus extern "C" { #endif // __cplusplus #include <lua.h> #ifdef __cplusplus }; #endif // __cplusplus int main( int argc, char** argv ) { // Lua VM letrehozasa lua_State* State = lua_open(); // Lua alap libek betoltese lua_openlibs( State ); // myfile.lua fajl futtatase lua_dofile( "myfile.lua" ); // MyFunc fuggveny elovetele lua_getfield( State, LUA_GLOBALSINDEX, "MyFunc" ); // elso parameter lua_pushinteger( State, 10 ); // a MyFunc fuggveny felhivasa 1 parameterrel, 0 result al lua_call( State, 1, 0 ); // Lua State lezarasa lua_close( State ); return 0; }
Mint a kódon láthatjuk egy egyszerű függvényhívás is már egy összetettebb probléma, hát még az objektum orientált függvények, tömb, table változók.
Szerencsére vannak megoldások arra, hogy a Lua is elfogadható és könnyen használható legyen. Mivel a projectekben fontos az, hogy ne hetek, hónapok menjenek el egy egy feladattal, hanem minél rövidebb idő alatt álljon elő olyan eredmény, ami kielégítő működést ad, ezért nem mindegy, hogy mennyire nehézkes a választott scriptnyelv importálása az alkalmazásunkba.
A Lua általam legkedveltebb C++ interface-e a LuaPlus. (Dokumentáció: http://wwhiz.com/LuaPlus/LuaPlus.html)
A LuaPlus al sokkal könnyedebbé válik a Lua használata, úgy, hogy nem vesztünk jelentős sebességet.
#include <stdio.h> #include <stdlib.h> #include "LuaPlus.h" using namespace LuaPlus; int main( int arcg, char** argv ) { // Lua VM letrehozasa es alap libek betoltese LuaState* State = LuaState::Create( true ); // myfile.lua fajl futtatasa State->DoFile( "myfile.lua" ); // MyFunc fuggveny elovetele LuaFunction<> MyFuncObject = State->GetGlobal( "MyFunc" ); // a MyFunc fuggveny felhivasa 1 parameterrel, 0 result al MyFuncObject( 10 ); // Lua State lezarasa LuaState::Destroy( State ); return 0; }
Remélem a példával jól látható, hogy a LuaPlus egy sokkal egyszerűbb, érthetőbb interface, mint az alap C Api. Rengeteg olyan lehetőséget biztosít, amivel komoly Lua bindet építhetünk össze úgy, hogy nem megy el rengeteg felesleges idő a fejlesztésre.
Ami még nagyon hasznos a LuaPlus ban, az az, hogy Nativ és Managed kódhoz is van DLL je, így amit C++ alkalmazásunkban használunk, majdnem ugyan úgy használhatjuk C# toolunk ban is! Ez megint csak csökkenti a fejlesztési időt.
Persze ez is olyan, mint sok más interface, az ember szeret belőle sajátot írni, ami jól is hangzik elsőre, de amint próbálunk a Lua C Api mélyére ásni, rá kell jöjjünk, hogy nem olyan egyszerű feladat.
Python
A Python jelentősen más fajta mint a Lua. Személyes véleményem szerint itt sokkal inkább a használhatóság, beépíthetőség volt a fő szempont, mintsem a gyorsaság. Ez egyben előnye, de hátránya is a scriptnek. Előny, a már említett fejlesztési idő miatt és hátrány, a sebesség vesztés miatt. A Python körülbelül 2 szer lassabb és 1.5 ször több memóriát eszik meg mint a Lua, habár vannak esetek, amikor Ő teljesít jobban. Jelenleg ugye a Pythonból úgymond 2 verzió létezik a 2.7 és a 3.2. Az itt megadott mérési eredmények a 3 as Pythonra vonatkoznak: http://shootout.alioth.debian.org/u32/benchmark.php?test=all&lang=python3&lang2=lua (az oldal nehézkesen működik, úgyhogy néha sokat kell próbálkozni)
De akkor lássuk hogy is építsük be a Pythont a kódunkba:
#include <Python.h> int main( int argc, char** argv ) { // Python VM letrehozasa Py_Initialize(); // hozzaadas a path hoz az aktualis konyvtarat // erdemes azt, ahol a python fajljaink vannak PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append(\".\")"); PyObject* ModName = PyString_FromString( "my_file" ); // a sajat fajlunk betoltese mint modul PyObject* Module = PyImport_Import( ModName ); if ( Module == NULL ) { // ha nem sikerult volna, akkor error es kilepes PyErr_Print(); return 1; } PyObject* Dict = PyModule_GetDict( Module ); // a fuggvenyunk lekerese PyObject* Func = PyDict_GetItemString( Dict, "MyFunction" ); // ellenorzes, hogy felhivhato-e if ( PyCallable_Check( Func ) ) { // parameter eloallitasa PyObject* Args = Py_BuildValue( "(i)", 14 ); // a fuggvenyunk felhivasa PyObject_CallObject( Func, Args ); } else { // hiba eseten hiba kiirasa es kilepes PyErr_Print(); return 1; } Py_XDECREF( Module ); Py_DECREF( ModName ); // VM torlese Py_Finalize(); return 0; }
Hát elsőre úgy tűnhet, hogy jóval hosszabb kód állt elő, de ennek egy része a fájlunk és annak függvényeinek betöltése, plusz itt van hiba kezelés is, ami jóval egyszerűbb, mint a Lua ban.
A kódból nekem az jött le, hogy sokkal “felhasználó” barátabb, könnyebb a kezelése, pointerekkel dolgozik, így talán kevesebb objektum létrehozás van, mint a LuaPlus ban.
Konklúzió
Mindazok mellett, hogy milyen komoly szavakat ismerek, azt kell mondjam, hogy mindkét script nyelv nagyon érdekes, a használatuk izgalmas és rengeteg sok lehetőség rejlik bennük. Igazából nem is nagyon tudnék dönteni, hogy most melyik tetszik jobban.
Mindkét nyelvhez található IDE és Debugger is szép számmal:
LUA
- IntellijIDEA– egy multi platform editor, eléggé sok feature el, LUA supportal, ahol saját(!) libeket lehet hozzá adni (van hozzá WoW és Rift Library). Ez nagyon hasznos tud lenni, mert így a saját projectunk függvényeit könnyedén be tudjuk illeszteni, ami segíti a fejlesztést
- LuaEdit– teljesen ingyenes és eléggé igényes editor és debugger a Luahoz, solution fájlokat kezel
- Scite– eléggé komoly, multi platform editor minden féle nyelvhez
- Addon Studio– érdemes megnézni, mit is lehet csinálni egy IDE vel és egy jó script engine el. Persze ez csak egy editor, de itt látható, hogy a WoW Addon / GUI rendszere mennyire flexibilis
- LuaStudio– egy eléggé komoly és letisztult Lua IDE és debugger
- Decoda – sajnos fizetős, de természetesen a legjobb IDE és debugger. Előző írásomban már áradoztam róla. Mindent tud, amit kell, főleg a remote debug a kielégítő benne!
Python
- GDB– most lehet páran megrökönyödnek, hogy hogy lehetséges, hogy a gdb-t valaha is szóba hozom, de jelenlegi munkám során találkozom vele és nem árt, ha a debugger rendszerekből nincs tíz féle. Persze egy designer vagy tester nem biztos, hogy valaha megbirkózna vele, de ettől még egy lehetőség
- WinPdb– egy multi platformos Python debugger, persze Python ban. Ingyenes, és egyszerűen mindent tud, amit egy debuggernek tudnia kell, mindamellett, hogy még igényes is! Természetesen alapból remote debugging, úgyhogy nagyvalószínűséggel a szerveren futó Python scripteket is gond nélkül debuggolja
- PyScripter– open source IDE és debugger, meglepően jó syntax highlight al és code completition el!
- WingWare – fizetős program nem is próbáltam ki, a WinPDB és PyScripter után azt hiszem teljesen felesleges
Mindent összevetve mindkét nyelvhez vannak iDE-k és Debuggerek is, mindkettőhöz jól használhatóak a programok, viszont a Pythonnak 1 nagy előnye van: GDB, hisz nem árt, ha az ember egyből tudja debuggolni, ha akár a saját alkalmazásában hal el a script.
Nekem személy szerint az újdonság erejével tetszik a Python nagyon és abban a szerencsés helyzetben vagyok, hogy szórakozhatok mindkettővel, de hogy melyiket használnám egy projectben … az még számomra is kérdéses, ehhez azért sokkal több konkrétum kell és egy jól megfontolt döntés!
Addig is remélem van akinek felkeltettem az érdeklődését az alábbi 2 irományommal és kedvet csináltam némi scriptelgetéshez! Jó szórakozást mindenkinek!