Zoeken…


Syntaxis

  • lua_State * L = lua_open (); // Maak een nieuwe VM-status; Lua 5.0
  • lua_State * L = luaL_newstate (); // Maak een nieuwe VM-status; Lua 5.1+
  • int luaL_dofile (lua_State * L, const char * bestandsnaam ); // Voer een lua-script uit met de opgegeven bestandsnaam met behulp van de opgegeven lua_State
  • void luaL_openlibs (lua_State * L); // Laad alle standaardbibliotheken in de opgegeven lua_State
  • void lua_close (lua_State * L); // Sluit de VM-status en laat alle bronnen vrij
  • void lua_call (lua_State * L, int nargs, int nresults); // Bel de luavalue op index - (nargs + 1)

Opmerkingen

Lua biedt ook een goede C API voor zijn virtuele machine. In tegenstelling tot VM zelf is de C API-interface stack-gebaseerd. De meeste functies die bedoeld zijn om met gegevens te worden gebruikt, zijn dus het toevoegen van een aantal dingen bovenop de virtuele stapel, of het verwijderen ervan. Ook moeten alle API-aanroepen zorgvuldig worden gebruikt binnen de stack en zijn beperkingen.

Over het algemeen kan alles wat beschikbaar is op de Lua-taal worden gedaan met behulp van de C API. Er is ook een aantal extra functies, zoals directe toegang tot het interne register, veranderingsgedrag van de standaard geheugenallocator of vuilnisman.

U kunt de meegeleverde Lua C API-voorbeelden samenstellen door het volgende uit te voeren op uw terminal:

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

Virtuele Lua-machine maken

#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;
}

Lua-functies aanroepen

#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;
 }

In het bovenstaande voorbeeld doen we deze dingen:

  • het maken en instellen van Lua VM zoals getoond in het eerste voorbeeld
  • een Lua-functie ophalen en duwen van de wereldwijde Lua-tabel naar virtuele stapel
  • tekenreeks "Hello C API" als invoerargument naar de virtuele stapel duwen
  • VM instrueren om een functie aan te roepen met één argument dat al op de stapel staat
  • sluiten en opruimen

NOTITIE:

lua_call() rekening mee dat lua_call() de functie lua_call() en de argumenten uit de stapel, waardoor alleen het resultaat lua_call() .

Het zou ook veiliger zijn om in plaats daarvan Lua protected call - lua_pcall() gebruiken.

Ingebouwde Lua-interpreter met aangepaste API en Lua-aanpassing

Laat zien hoe een Lua-interpreter in C-code wordt ingesloten, stel een door C gedefinieerde functie bloot aan Lua-script, evalueer een Lua-script, roep een C-gedefinieerde functie op vanuit Lua en roep een Lua-gedefinieerde functie op vanuit C (de host).

In dit voorbeeld willen we dat de stemming wordt bepaald door een Lua-script. Hier is 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

Let op, mood() wordt niet in het script genoemd. Het is zojuist gedefinieerd dat de host-toepassing moet worden aangeroepen. Merk ook op dat het script een functie genaamd hostgetversion() die niet in het script is gedefinieerd.

Vervolgens definiëren we een host-applicatie die 'mood.lua' gebruikt. Hier is de '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;
}

En hier is de output:

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

Zelfs nadat we 'hostlua.c' hebben gecompileerd, kunnen we 'mood.lua' nog wijzigen om de uitvoer van ons programma te wijzigen!

Tafel manipulatie

Als u een index op een tafel wilt openen of wijzigen, moet u de tafel op de een of andere manier in de stapel plaatsen.
Laten we aannemen dat voor deze voorbeelden uw tabel een globale variabele is met de naam tbl.

De inhoud op een bepaalde index krijgen:

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
}

Zoals we hebben gezien, hoef je alleen maar de tafel in de stapel te duwen, de index te duwen en lua_gettable te bellen. het argument -2 betekent dat de tabel het tweede element vanaf de bovenkant van de stapel is.
lua_gettable activeert metamethoden. Als u geen metamethoden wilt activeren, gebruikt u in plaats daarvan lua_rawget. Het gebruikt dezelfde argumenten.

De inhoud instellen op een bepaalde index:

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;
}

Dezelfde oefening als het ophalen van de inhoud. Je moet de stapel duwen, de index duwen en vervolgens de waarde in de stapel duwen. daarna noem je lua_settable. het argument -3 is de positie van de tabel in de stapel. Gebruik lua_rawset in plaats van lua_settable om te voorkomen dat metamethoden worden geactiveerd. Het gebruikt dezelfde argumenten.

De inhoud overbrengen van een tabel naar een andere:

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;
}

Nu brengen we alles samen wat we hier hebben geleerd. Ik plaats de stapelinhoud op de reacties zodat je niet verdwaalt.

We plaatsen beide tabellen in de stapel, duwen de index van tabel 1 in de stapel en krijgen de waarde op tbl1.index1 . Let op het argument -3 op gettable. Ik kijk naar de eerste tafel (derde van boven) en niet de tweede. Vervolgens drukken we op de index van de tweede tabel, kopiëren we de tbl1.index1 naar de bovenkant van de stapel en roepen dan lua_settable op het 4e item van boven.

Voor het schoonmaken heb ik het bovenste element verwijderd, zodat alleen de twee tafels op de stapel blijven.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow