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.
-- 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++.
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.
{
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.
Grazie degli articoli!
🙂
🙂