Recherche…


Syntaxe

  • lua_State * L = lua_open (); // Crée un nouvel état de VM; Lua 5.0
  • lua_State * L = luaL_newstate (); // Crée un nouvel état de VM; Lua 5.1+
  • int luaL_dofile (lua_State * L, const char * filename ); // Exécuter un script lua avec le nom de fichier donné en utilisant le lua_State spécifié
  • annuler luaL_openlibs (lua_State * L); // Charge toutes les bibliothèques standard dans le lua_State spécifié
  • annuler lua_close (lua_State * L); // Ferme l'état de la VM et libère les ressources à l'intérieur
  • void lua_call (lua_State * L, int nargs, int nresults); // Appelle la luavalue à l'index - (nargs + 1)

Remarques

Lua fournit également une API C correcte à sa machine virtuelle. Contrairement à la VM elle-même, l'interface de l'API C est basée sur la pile. Ainsi, la plupart des fonctions destinées à être utilisées avec des données consistent à ajouter des éléments sur la pile virtuelle ou à en retirer. De plus, tous les appels d'API doivent être utilisés avec soin dans la pile et ses limites.

En général, tout ce qui est disponible sur le langage Lua peut être fait en utilisant son API C. En outre, il existe des fonctionnalités supplémentaires telles que l'accès direct au registre interne, le changement de comportement de l'allocateur de mémoire standard ou du garbage collector.

Vous pouvez compiler les exemples d'API Lua C fournis en exécutant les opérations suivantes sur votre terminal:

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

Création d'une machine virtuelle Lua

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

Fonctions d'appel 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;
 }

Dans l'exemple ci-dessus, nous faisons ces choses:

  • créer et configurer Lua VM comme indiqué sur le premier exemple
  • obtenir et pousser une fonction Lua de la table Lua globale sur une pile virtuelle
  • pousser la chaîne "Hello C API" comme argument d'entrée sur la pile virtuelle
  • demander à VM d'appeler une fonction avec un argument qui est déjà sur la pile
  • fermeture et nettoyage

REMARQUE:

N'oubliez pas que lua_call() la fonction et ses arguments dans la pile, ne laissant que le résultat.

En outre, il serait plus sûr d'utiliser Lua protected call - lua_pcall() place.

Interpréteur Lua intégré avec personnalisation de l'API et de Lua

Démontrer comment intégrer un interpréteur lua en code C, exposer une fonction C-defined au script Lua, évaluer un script Lua, appeler une fonction C-defined depuis Lua et appeler une fonction définie par Lua à partir de C (l'hôte).

Dans cet exemple, nous voulons que l’humeur soit définie par un script Lua. Voici 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

Notez que mood() n'est pas appelé dans le script. Il est juste défini pour l'application hôte à appeler. Notez également que le script appelle une fonction appelée hostgetversion() qui n'est pas définie dans le script.

Ensuite, nous définissons une application hôte utilisant 'mood.lua'. Voici le '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;
}

Et voici la sortie:

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

Même après avoir compilé 'hostlua.c', nous sommes toujours libres de modifier 'mood.lua' pour modifier la sortie de notre programme!

Manipulation de table

Pour accéder ou modifier un index sur une table, vous devez en quelque sorte placer la table dans la pile.
Supposons, pour cet exemple, que votre table est une variable globale nommée tbl.

Obtenir le contenu à un index particulier:

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
}

Comme nous l'avons vu, il suffit de pousser la table dans la pile, de pousser l'index et d'appeler lua_gettable. L'argument -2 signifie que la table est le deuxième élément du haut de la pile.
lua_gettable déclenche les méthodes de métamorphose. Si vous ne souhaitez pas déclencher de métaméthode, utilisez plutôt lua_rawget. Il utilise les mêmes arguments.

Définition du contenu à un index particulier:

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

Le même exercice que l'obtention du contenu. Vous devez pousser la pile, appuyer sur l’index puis pousser la valeur dans la pile. après cela, vous appelez lua_settable. l'argument -3 est la position de la table dans la pile. Pour éviter de déclencher des méthodes, utilisez lua_rawset au lieu de lua_settable. Il utilise les mêmes arguments.

Transférer le contenu d'une table à une autre:

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

Nous rassemblons maintenant tout ce que nous avons appris ici. Je mets le contenu de la pile sur les commentaires afin que vous ne vous perdiez pas.

Nous mettons les deux tables dans la pile, poussez l'index de la table 1 dans la pile et obtenez la valeur à tbl1.index1 . Notez l'argument -3 sur gettable. Je regarde la première table (la troisième en partant du haut) et non la seconde. Ensuite, nous poussons l'index de la deuxième table, copions le tbl1.index1 en haut de la pile, puis appelons lua_settable , sur le 4ème élément depuis le haut.

Pour l'entretien ménager, j'ai purgé l'élément supérieur, de sorte que seules les deux tables restent sur la pile.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow