Narzędzia użytkownika

Narzędzia witryny


c_i_lua

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Previous revision
Next revision
Previous revision
c_i_lua [2010/12/28 14:41]
sjablon1
c_i_lua [2010/12/29 12:22] (aktualna)
sjablon1
Linia 20: Linia 20:
  
  
-=== Podstawy języka Lua ===+==== Podstawy języka Lua ====
  
-BUUU+Strona ma na celu ukazanie sposobów i możliwości integracji języków C++ oraz Lua, jednak przedstawię krótko podstawy języka Lua wraz z przykładami. W celu dogłębnego poznania składni i możliwość języka polecam dokumentacje umieszczoną na stronie internetowej.
  
-=== Łączenie z C++ === +Na początek standardowy Hello World (Listing 1)
-BUUU+
  
-=== Więcej informacji ===+**Listing 1** - program Hello World w Lua
  
-http://​www.lua.org - dokumentacja języka, biblioteki i narzędzia.+<code cpp>
  
-http://​code.google.com/​p/​luaforwindows/ ​biblioteki i narzędzi dla systemu Windows.+-- HelloWorld.lua 
 +print("​Hello from Lua!"​);​ 
 +--[[ 
 +Przykład komentarza 
 +umieszczonego w kilku liniach 
 +]]
  
-http://​luaforge.net/​projects/​luaforunix/​ - biblioteki i narzędzi dla systemu Unix.+</code>
  
-http://​www.luarocks.org/​ - deployment and management system for Lua modules. ​ 
  
 +=== Konwencje leksykalne ===
 +
 +  * W języku Lua identyfikatory mogą się składać z dowolnego łańcucha znaków alfanumerycznych lub znaku _.
 +  * Ograniczeniami są: zakaz rozpoczynania identyfikatora od cyfry oraz słowa zastrzeżone jak //and//, //or//, //break//, //else// itp.
 +  * Lua rozróżnia wielkość liter, więc For będzie oznaczał identyfikator zaś for będzie dotyczył pętli.
 +  * Komentarze rozpoczyna się podwójnym myślnikiem ​ i działa analogicznie jak  w C++, ignorowane są wszystkie znaki, aż do końca linii.
 +  * Istnieje również możliwość komentowania całego bloku kodu na kształt znanych z języka C, które w Lua zastąpione jest ciągiem --[[".
 +
 +
 +=== Typy danych i wyrażenia ===
 +
 +
 +W Lua podobnie jak w innych językach skryptowych nie deklarujemy typów zmiennych. Zamiast tego każda zmienna ma dynamiczny typ określany przez jej wartość.
 +
 +Istnieje 8 podstawowych typów danych:
 +
 +  * //nil// - przyjmuje jedną wartość nil, która określa brak konkretnej wartości (często nil jest stosowany do określenia zmienną niezainicjalizowaną);​
 +  * //boolean// - standardowe wartości boolowskie true/false;
 +  * //number// - liczba rzeczywista,​ zmiennoprzecinkowa;​
 +  * //string// - standardowy łańcuch znaków;
 +  * //​userdata//​ - typ danych pozwalajacy na przetrzymywanie dowolnych danych z języka C(np. wskaźników);​
 +  * //​function//​ - ciąg wykonywalnych instrukcji, funkcje mogą być deklarowane wewnątrz innych funkcji lub być zwracane z innej funkcji
 +  *// thread// - wątek w Lua;
 +  * //table// - tablica asocjacyjna(więcej informacji w dalszej części strony);
 +
 +Ciekawym mechanizmem języka jest poleceniem //type// pozwalające na sprawdzenie typu zmiennej. Przykład pokazano na Listingu 2.
 +
 +**Listing 2** - przykład polecenia type w Lua.
 +
 +<code cpp>
 +
 +print(type(a)) --> nil (zmienna '​a'​ nie została zainicjalizowana)
 +a = 10
 +print(type(a)) --> number
 +a = print
 +a(type(a)) --> function
 +
 +</​code>​
 +
 +
 +W Lua dostępne są następujące operatory:
 +
 +  * Operatory arytmetyczne:​ +, -, *, /;
 +  * Operatory porównania:​ ==, ~=, <, >, <=, >=-
 +  * Operatory logiczne: //and//, //or//, //not//
 +
 +=== Instrukcje i funkcje ===
 +
 +Lua posiada standardowe instrukcje znane z języków Pascal/C:
 +
 +  * instrukcja przypisania =;
 +  * instrukcje warunkowe, if/​elseif/​else/​end;​
 +  * pętle, for/do/end, while,​do,​end,​ repeat/​until;​
 +  * wywołanie funkcji;
 +  * lokalna deklaracja zmiennych;
 +
 +
 +**Listing 3** - przykład stosowania funkcji i warunków logicznych, funkcja rekurencyjna obliczająca silnie.
 +
 +<code cpp>
 +
 +-- obliczenie n!
 +function factorial (n)
 +if n == 1 then
 +return 1;
 +else
 +return n * factorial(n-1);​
 +end
 +end
 +-- obliczenie 5!
 +print(factorial(5));​ --> 120
 +
 +</​code>​
 +
 +=== Tablice ===
 +
 +Najistotniejszymi strukturami danych w Lua są tablice asocjacyjne reprezentowane przez kolekcję par (klucz, wartość). Kluczem może być wszystko poza
 +wartością //nil//. Elementami tablicy mogą być wszystkie wartości podstawowych typów Lua. Oznacza to, że również mogą to być omawiane w tym miejscu Tablice. Pozwala to na tworzenie takich struktur jak lista, wektor, kolejka czy stos.
 +
 +Listing 4 pokazuje przykłady wykorzystania tablic w Lua realizując proste zbiory danych, listę jednokierunkową,​ czy strukturę zawierającą zarówno atrybuty jak i metody.
 +
 +
 +**Listing 4** - przykład wykorzystania tablic do realizacji zbiorów danych.
 +
 +<code cpp>
 +
 +
 +-- prosty wektor liczb
 +squares = {1, 4, 9, 16, 25, 36, 49, 64, 81}
 +-- zbiór danych
 +creature = { name = "​Ghoul",​ health = 100 }
 +print(creature["​name"​]);​ --> Ghoul
 +print(creature.name);​ --> Ghoul
 +-- lista
 +list = nil;
 +list = {next = list, value = 2};
 +list = {next = list, value = "​test"​};​
 +list = {next = list, value = math.pi};
 +ptr = list;
 +while ptr do
 +print(ptr.value);​
 +ptr = ptr.next;
 +end; --> 3.141592 test 2
 +-- struktura/​klasa
 +Vec3 = {};
 +Vec3.new = function(x, y, z)
 +return {x=x, y=y, z=z, length=function() return math.sqrt(x*x+y*y+z*z) end;}
 +end;
 +v = Vec3.new(4, 2, 4);
 +print(v:​length());​ --> 6
 +
 +</​code>​
 +
 +
 +=== Biblioteka standardowa Lua ===
 +
 +Lua jak każdy porządny język, wyposażona została w bogatą standardową bibliotekę zawierającą bogaty zestaw narzędzi wyższego poziomu. Należą do niej następujące moduły:
 +
 +  * funkcje wejścia/​wyjścia;​
 +  * funkcje systemowe;
 +  * operacje na łańcuchach znaków;
 +  * operacje na tablicach;
 +  * obsługa wątków;
 +  * funkcje matematyczne;​
 +
 +Poniższy kod pokazuje kilka przykładów wykorzystania biblioteki standardowej.
 +
 +**Listing 5** Wykorzystanie biblioteki standardowej Lua
 +
 +<code cpp>
 +
 +-- losowanie liczb
 +math.randomseed(os.time())
 +print(math.random(10));​ -- wyświetlenie liczby wylosowanej z przedziału [1,10]
 +
 +-- obliczenie wartości cos(pi/5)
 +print(math.cos(math.pi*0.2));​
 +
 +
 +-- zapis do pliku
 +f = assert(io.open("​output.txt",​ "​w"​))
 +f:​write("​test"​);​
 +f:close();
 +
 +</​code>​
 +
 +==== Integracja z C++ ====
 +
 +Zapoznaliśmy się już z podstawami języka Lua, część przejść do najważniejszej sprawy czyli integracji z językiem C++.
 +
 +=== Przygotowanie do pracy z Lua ===
 +
 +W celu rozpoczęcia pracy z Lua musimy wykonać dwie następujące operacje:
 +
 +  - Dołączenie do projektu skompilowaną bibliotekę Lua oraz dołączyć w kodzie nagłówki Lua (lua.h, lualib.h i lauxlib.h)
 +  - Należy zapamiętać,​ że skrypty Lua wykonywane są na maszynie wirtualnej, musimy więc ją zainicjować.
 +
 +Prosty przykład ukazujący wspomniane operacje i wywołujący z poziomu kodu C++ skrypt Lua pokazany jest na Listingu 6.
 +
 +**Listing 6** Inicjalizacja maszyny wirtualnej Lua i wywołanie skryptu Lua z poziomu kodu C++
 +
 +<code cpp>
 +
 +#include <​iostream>​
 +
 +// dołączenie nagłówków Lua
 +extern "​C"​
 +{
 +    #include "​lua.h"​
 +    #include "​lualib.h"​
 +    #include "​lauxlib.h"​
 +}
 +
 +
 +int main()
 +{
 +    // utworzenie maszyny wirtualnej Lua. 
 +    lua_State* L = lua_open();
 +
 +    // inicjalizacja standardowych bibliotek
 +    luaL_openlibs(L);​
 +    ​
 +    // wczytanie skryptu Lua
 +    if (luaL_dofile(L,​ "​zpr.lua"​))
 +    {
 +        // Walidacja wcztania skryptu
 +        std::cout << "Error while running script: " << lua_tostring(L,​ -1) << std::endl;
 +        return 1;
 +    }
 +
 +    // zamknięcie maszyny wirtualnej
 +    lua_close(L);​
 +    return 0;
 +}
 +
 +
 +
 +</​code>​
 +
 +
 +=== Wywoływanie funkcji Lua w kodzie C++ ===
 +
 +Potrafimy już z poziomu kodu C++ zainicjalizować maszynę wirtualną Lua i uruchomić skrypt napisany w Lua. Przejdźmy krok dalej - spróbujmy wywołać funkcję zdefiniowaną w skrypcie Lua z poziomu kodu C++. Zacznijmy od przykładowej funkcji obliczającą różnicę dwóch liczb.
 +
 +**Listing 7** Funkcja Lua obliczającą różnicę dwóch liczb.
 +
 +<code cpp>
 +
 +--sub.lua
 +
 +function(x,​y)
 +return x - y
 +end
 +
 +
 +</​code>​
 +
 +Aby umożliwić wywoływanie funkcji ze skryptu Lua musimy zdefiniować kodzie C++ funkcję, w której odłożymy na stos parametry funkcji, a następnie
 +zdejmiemy ze stosu wartość zwracaną przez funkcję. Ilustruje to poniższy przykład:
 +
 +**Listing 8** Przykład wywołania funkcji Lua w kodzie C++.
 +
 +<code cpp>
 +
 +#include <​iostream>​
 +
 +// dołączenie nagłówków Lua
 +extern "​C"​
 +{
 +    #include "​lua.h"​
 +    #include "​lualib.h"​
 +    #include "​lauxlib.h"​
 +}
 +
 +
 +// Interpretator Lua
 +lua_State* L;
 +
 +
 +// Funkcja wywołującą funkcję ze skryptu Lua i zwracająca otrzymany wynik
 +int luaSub(int x, int y)
 +{
 +
 +    int sub = 0;
 +    ​
 +    // nazwa funkcji w pliku sub.lua
 +    lua_getglobal(L,​ "​sub"​);​
 +
 +    // pierwszy argument
 +    lua_pushnumber(L,​ x);
 +
 +    // drugi agrument ​
 +    lua_pushnumber(L,​ y);
 +
 +    // wywołanie funkcji z dwoma argumentami i jedną wartością zwracaną
 +    lua_call(L, 2, 1);
 +
 +    // pobranie wyniku i zdjęcie ze stosu
 +    sub = static_cast<​int>​(lua_tointeger(L,​ -1));
 +
 +    lua_pop(L, 1);
 +    return sub;
 +}
 +
 +int main()
 +{
 +    int sub = 0;
 +
 +    // utworzenie maszyny wirtualnej Lua. 
 +    L = lua_open();
 + 
 +    // inicjalizacja standardowych bibliotek
 +    luaL_openlibs(L);​
 + 
 +    // wczytanie skryptu Lua
 +    if (luaL_dofile(L,​ "​sub.lua"​))
 +    {
 +        // Walidacja wczytania skryptu
 +        std::cout << "Error while running script: " << lua_tostring(L,​ -1) << std::endl;
 +        return 1;
 +    }
 + 
 +    // wywołanie funkcji
 +    sub = luaSub( 10, 15 );
 +
 +    std::cout << "​Substraction:​ " << sub << std::endl;
 +    ​
 +    // zamknięcie maszyny wirtualnej
 +    lua_close(L);​
 +    return 0;
 +
 +}
 +
 +</​code>​
 +
 +
 +=== Wywoływanie funkcji C++ w kodzie Lua ===
 +
 +Spróbujmy zrobić wykonać to samo zadanie odwrotni. Wywołajmy funkcję napisaną w C++ w kodzie Lua. Funkcje w Lua są wywoływane używając wskaźnika na funkcję:
 +
 +''​typedef int (*lua_CFunction) (lua_State *L);''​
 +
 +Wynika z tego, że funkcje przyjmują jako argument interpretator Lua i zwracają wartość int. Napiszmy funkcję w C++, która będzie liczyła sumę liczb przekazanych do funkcji, których liczba będzie zmienna:
 +
 +**Listing 9** Funkcja liczącą sumę podanych liczb w C++ wywoływana z poziomu kodu Lua.
 +
 +<code cpp>
 +
 +
 +
 +#include <​iostream>​
 +
 +// dołączenie nagłówków Lua
 +extern "​C"​
 +{
 +    #include "​lua.h"​
 +    #include "​lualib.h"​
 +    #include "​lauxlib.h"​
 +}
 +
 +
 +// Interpretator Lua
 +lua_State* L;
 +
 +// Funkcja przygotowana do wywołania w kodzie Lua
 +static int suma(lua_State *L)
 +{
 +    // pobranie liczby argumentów
 +    int n = lua_gettop(L);​
 +
 +    int suma = 0;
 +    ​
 +    // sumowanie argumentów
 +    for (int i = 0; i < n; ++i)
 +        suma += lua_tonumber(L,​ i);
 +
 +    // zwrócenie sumy
 +    lua_pushnumber(L,​ suma)
 +    ​
 +    // zwracamy ilość wartości zwracanych przez funkcję
 +    return 1;
 +}
 +
 +
 +int main()
 +{
 +    int sub = 0;
 +
 +    // utworzenie maszyny wirtualnej Lua. 
 +    L = lua_open();
 + 
 +    // inicjalizacja standardowych bibliotek
 +    luaL_openlibs(L);​
 + 
 +    // rejestracja funkcji suma pod nazwą f_suma
 +    lua_register(L,​ "​f_suma",​ suma);
 +
 +    // wczytanie skryptu Lua
 +    if (luaL_dofile(L,​ "​zpr.lua"​))
 +    {
 +        // Walidacja wczytania skryptu
 +        std::cout << "Error while running script: " << lua_tostring(L,​ -1) << std::endl;
 +        return 1;
 +    }
 + 
 +
 +    ​
 +    // zamknięcie maszyny wirtualnej
 +    lua_close(L);​
 +    return 0;
 +
 +}
 +
 +</​code>​
 +
 +
 +**Listing 10** Przykład wywołania w skrypcie Lua funkcji napisanych w C++
 +<code cpp>
 +
 +--zpr.lua
 +suma = f_suma(10, 20, 30, 40, 50)
 +print("​Suma wynosi: ", suma)
 +</​code>​
 +
 +
 +
 +==== Więcej informacji ====
 +
 +http://​www.lua.org - strona domowa Lua.
 +
 +http://​www.lua.org/​manual/​5.1 - dokumentacja on-line Lua.
 +
 +http://​lua-users.org/​wiki/​ -  zbiór artykułów,​ dodatków i przykładów Lua
 +
 +http://​www.inf.puc-rio.br/​~roberto/​pil2/​ - programowanie w Lua
 +
 +http://​code.google.com/​p/​luaforwindows/​ - biblioteki i narzędzi dla systemu Windows.
 +
 +http://​luaforge.net/​projects/​luaforunix/​ - biblioteki i narzędzi dla systemu Unix.
  
 +http://​www.luarocks.org/​ - deployment and management system for Lua modules.
  
c_i_lua.1293543696.txt.gz · ostatnio zmienione: 2010/12/28 14:41 przez sjablon1