Lua/C++ : Passaggio Di Parametri

Aldrin Apollo 11

Abbiamo visto negli articoli precedenti come utilizzare funzioni C++ all’interno dei script Lua (e viceversa). Ci eravamo però dimenticati di dire come fare a passare dati sottoforma di parametri fra Lua e C++. Ora è giunto il momento di colmare questa lacuna.

Il passaggio di parametri fra funzioni Lua e C++ è, come potete immaginare, un aspetto fondamentale della programmazione mista Lua/C++. Tuttavia, nonostante la procedura non sia delle più intuitive, è estremamente semplice. Ma partiamo da un esempio, consideriamo il seguente script Lua.

-- Questo è un esempio di script Lua che
-- utilizza al suo interno una funzione C++.

print("Fattoriale di 5!")
print("Implementato in C++ con amore!")
print(Factorial(5))

Un caso d’uso dei più banali consiste nell’usare all’interno di uno script Lua funzioni C++ per le operazioni CPU-intensive. Possiamo trovare un esempio spicciolo nel listato Lua precedente. La funzione Factorial per il calcolo del fattoriale è notoriamente una funzione che necessita di una buona velocità. Così, invece di implementarla in Lua useremo una funzione C++. Vediamo quindi il codice C++.

LuaGrip* pLua;

int factorial_recursive(int n)
{
    if (n==1) return 1;
    return n * factorial_recursive(n-1);
}

LuaGlue _Factorial(struct lua_State *pLuaState)
{
    /* Ricaviamo i parametri della funzione.
     *
     * La funzione Lua agganciata a questa funzione C++
     * ha la seguente struttura:
     *
     *     int Factorial(int n)
     *
     * Dobbiamo quindi recuperare il primo int.
     */

     double n;
     n = pLua->GetNumberArgument(1);
     
     /* Calcoliamo il fattoriale */
     int res = factorial_recursive(n);
     
     /* Restituiamo il valore di ritorno */
     pLua->PushNumber(res);
     
     return 1;
}

La funzione _Factorial è la classica funzione LuaGlue. La domanda viene spontanea: come fare a passare il valore 5 alla funzione Factorial? E come fare a restituire il valore finale? Andiamo per passi:

La prima cosa che facciamo nella funzione _Factorial è proprio recuperare il parametro 5. Facciamo questo tramite la funzione LuaGrip double GetNumberArgument(int argnum). La funzione prende in ingresso il numero del parametro da recuperare, nel nostro caso abbiamo bisogno del primo parametro e quindi usiamo semplicemente il numero 1. Come valore di ritorno la funzione restituisce un double.

A questo punto passiamo il valore recuperato ad una funzione “tradizionale” factorial_recursive che calcola il valore del fattoriale nel modo “classico”.

Infine, il valore di ritorno viene restituito a Lua grazie alla funzione LuaGrip void PushNumber(res).

Mi raccomando non dimenticate di ritornare un 1 alla fine altrimenti Lua interpreterà il mancato valore di ritorno come un errore nella funzione.

A questo punto scriviamo il main che, in questo caso, non farà altro che agganciare la funzione Factorial a Lua e lanciare lo script.

int main()
{
    pLua = new LuaGrip();
    pLua->AddFunction("Factorial",_Factorial);
    pLua->RunScript("fac.lua");
    delete pLua;
}

A questo punto l’integrazione è completa! Non c’è molto altro da sapere :)

Tuttavia continuerò a presentare esempi. Nel prossimo articolo su Lua/C++ ho intenzione di parlare su come utilizzare Lua per la programmazione event-driven.

3 comments on “Lua/C++ : Passaggio Di Parametri