Ricerca…


Sintassi

  • lua_State * L = lua_open (); // Crea un nuovo stato VM; Lua 5.0
  • lua_State * L = luaL_newstate (); // Crea un nuovo stato VM; Lua 5.1+
  • int luaL_dofile (lua_State * L, const char * nomefile ); // Esegui uno script lua con il nome file specificato usando lua_State specificato
  • void luaL_openlibs (lua_State * L); // Carica tutte le librerie standard nel lua_State specificato
  • void lua_close (lua_State * L); // Chiudi lo stato della VM e rilascia tutte le risorse al suo interno
  • void lua_call (lua_State * L, int nargs, int nresults); // Chiama il luavalue all'indice - (nargs + 1)

Osservazioni

Anche Lua fornisce un'API C adeguata alla sua macchina virtuale. Al contrario della VM stessa, l'interfaccia API C è basata sullo stack. Quindi, la maggior parte delle funzioni destinate a essere utilizzate con i dati consiste nell'aggiungere alcune cose in cima allo stack virtuale o rimuoverle. Inoltre, tutte le chiamate API devono essere utilizzate con attenzione all'interno dello stack e le sue limitazioni.

In generale, tutto ciò che è disponibile sulla lingua Lua può essere fatto usando la sua API C. Inoltre, ci sono alcune funzionalità di aggiunta come l'accesso diretto al registro interno, il comportamento delle modifiche di allocatore di memoria standard o garbage collector.

Puoi compilare gli esempi di API Lua C eseguendo il seguente comando sul tuo terminale:

$ gcc -Wall ./example.c -llua -ldl -lm

Creazione di Lua Virtual Machine

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

int main(void)
{
5.1
  /* Start by creating a new VM state */
  lua_State *L = luaL_newstate();

  /* Load standard Lua libraries: */
  luaL_openlibs(L);
5.1
  /* For older version of Lua use lua_open instead */
  lua_State *L = lua_open();

  /* Load standard libraries*/
  luaopen_base(L);
  luaopen_io(L);
  luaopen_math(L);
  luaopen_string(L);
  luaopen_table(L);
    /* do stuff with Lua VM. In this case just load and execute a file: */
    luaL_dofile(L, "some_input_file.lua");

    /* done? Close it then and exit. */
    lua_close(L);

    return EXIT_SUCCESS;
}

Chiamando le funzioni Lua

#include <stdlib.h>

#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>

int main(void)
{
    lua_State *lvm_hnd = lua_open();
    luaL_openlibs(lvm_hnd);

    /* Load a standard Lua function from global table: */
    lua_getglobal(lvm_hnd, "print");

    /* Push an argument onto Lua C API stack: */
    lua_pushstring(lvm_hnd, "Hello C API!");

    /* Call Lua function with 1 argument and 0 results: */
    lua_call(lvm_hnd, 1, 0);

    lua_close(lvm_hnd);

    return EXIT_SUCCESS;
 }

Nell'esempio sopra stiamo facendo queste cose:

  • creando e configurando Lua VM come mostrato nel primo esempio
  • ottenere e spingere una funzione Lua dalla tabella Lua globale allo stack virtuale
  • spingendo la stringa "Hello C API" come argomento di input sullo stack virtuale
  • istruire VM per chiamare una funzione con un argomento che è già in pila
  • chiusura e pulizia

NOTA:

Ricordatevi che lua_call() apre la funzione e gli argomenti dalla pila lasciano solo il risultato.

Inoltre, sarebbe più sicuro usare invece Lua protected call - lua_pcall() .

Interprete Lua integrato con API personalizzata e personalizzazione Lua

Dimostrare come incorporare un interprete lua nel codice C, esporre una funzione definita da C allo script Lua, valutare uno script Lua, chiamare una funzione definita da C da Lua e chiamare una funzione definita da Lua da C (l'host).

In questo esempio, vogliamo che lo stato d'animo venga impostato da uno script Lua. Ecco mood.lua:

-- Get version information from host
major, minor, build = hostgetversion()
print( "The host version is ", major, minor, build)
print("The Lua interpreter version is ", _VERSION)

-- Define a function for host to call
function mood( b )

    -- return a mood conditional on parameter
    if (b and major > 0) then
        return 'mood-happy'
    elseif (major == 0) then
        return 'mood-confused'
    else
        return 'mood-sad'
    end
end

Si noti che mood() non viene chiamato nello script. È appena definito per l'applicazione host da chiamare. Si noti inoltre che lo script chiama una funzione chiamata hostgetversion() che non è definita nello script.

Successivamente, definiamo un'applicazione host che utilizza 'mood.lua'. Ecco l'hostlua.c:

#include <stdio.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

/* 
 * define a function that returns version information to lua scripts
 */
static int hostgetversion(lua_State *l)
{
    /* Push the return values */
    lua_pushnumber(l, 0);
    lua_pushnumber(l, 99);
    lua_pushnumber(l, 32);

    /* Return the count of return values */
    return 3;
}

int main (void)
{
    lua_State *l = luaL_newstate();
    luaL_openlibs(l);

    /* register host API for script */
    lua_register(l, "hostgetversion", hostgetversion);

    /* load script */
    luaL_dofile(l, "mood.lua");

    /* call mood() provided by script */
    lua_getglobal(l, "mood");
    lua_pushboolean(l, 1);
    lua_call(l, 1, 1);

    /* print the mood */
    printf("The mood is %s\n", lua_tostring(l, -1));
    lua_pop(l, 1);

    lua_close(l);
    return 0;
}

Ed ecco l'output:

The host version is     0    99    32
Lua interpreter version is     Lua 5.2
The mood is mood-confused

Anche dopo aver compilato 'hostlua.c', siamo ancora liberi di modificare 'mood.lua' per modificare l'output del nostro programma!

Manipolazione della tabella

Per accedere o modificare un indice su un tavolo, è necessario in qualche modo posizionare la tabella nello stack.
Supponiamo, per questo esempio, che la tua tabella sia una variabile globale chiamata tbl.

Ottenere il contenuto in un indice particolare:

int getkey_index(lua_State *L)
{
  lua_getglobal(L, "tbl");    // this put the table in the stack
  lua_pushstring(L, "index"); // push the key to access
  lua_gettable(L, -2);        // retrieve the corresponding value; eg. tbl["index"]

  return 1;                   // return value to caller
}

Come abbiamo visto, tutto ciò che devi fare è spingere il tavolo nello stack, premere l'indice e chiamare lua_gettable. l'argomento -2 indica che la tabella è il secondo elemento dalla cima dello stack.
lua_gettable attiva metamethods. Se non vuoi attivare metamethod, usa invece lua_rawget. Usa gli stessi argomenti.

Impostazione del contenuto in un indice particolare:

int setkey_index(lua_State *L)
{
  // setup the stack
  lua_getglobal(L, "tbl");
  lua_pushstring(L, "index");
  lua_pushstring(L, "value");
  // finally assign the value to table; eg. tbl.index = "value"
  lua_settable(L, -3);

  return 0;
}

Lo stesso trapano come ottenere il contenuto. Devi spingere la pila, spingere l'indice e quindi inserire il valore nella pila. dopodiché chiami lua_settable. l'argomento -3 è la posizione della tabella nello stack. Per evitare di innescare metamethods, usa lua_rawset invece di lua_settable. Usa gli stessi argomenti.

Trasferimento del contenuto da una tabella a un'altra:

int copy_tableindex(lua_State *L)
{
    lua_getglobal(L, "tbl1"); // (tbl1)
    lua_getglobal(L, "tbl2");// (tbl1)(tbl2)
    lua_pushstring(L, "index1");// (tbl1)(tbl2)("index1")
    lua_gettable(L, -3);// (tbl1)(tbl2)(tbl1.index1)
    lua_pushstring(L, "index2");// (tbl1)(tbl2)(tbl1.index1)("index2")
    lua_pushvalue(L, -2); // (tbl1)(tbl2)(tbl1.index1)("index2")(tbl1.index1)
    lua_settable(L, -4);// (tbl1)(tbl2)(tbl1.index1)
    lua_pop(L, 1);

    return 0;
}

Ora stiamo mettendo insieme tutto ciò che abbiamo imparato qui. Inserisco il contenuto dello stack nei commenti in modo da non perderlo.

tbl1.index1 entrambe le tabelle nello stack, inseriamo l'indice della tabella 1 nello stack e otteniamo il valore su tbl1.index1 . Notare l'argomento -3 su gettable. Sto guardando il primo tavolo (terzo dall'alto) e non il secondo. Quindi inseriamo l'indice della seconda tabella, copiamo il file tbl1.index1 in cima allo stack e quindi richiamiamo lua_settable , sul quarto elemento dall'alto.

Per l'amor di pulizia, ho eliminato l'elemento superiore, quindi solo i due tavoli rimangono in pila.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow