Red de conocimiento informático - Material del sitio web - Cómo integrar scripts LUA en C++

Cómo integrar scripts LUA en C++

1. Cree un motor Lua

LuaWrap lua; o LuaWrap* lua = new LuaWrap;

Crear un objeto LuaWrap es crear un motor de script Lua. Dependiendo de la naturaleza de Lua, puedes crear cualquier número de motores Lua, incluso distribuidos entre diferentes subprocesos.

2. Cargar y ejecutar scripts

Puedes cargar scripts Lua desde el búfer:

lua.LoadString(

"print ( 'Hello World')"

);

Por supuesto, también puedes cargar y ejecutar scripts Lua desde archivos:

Lua.LoadFile(". / test.lua");

Los scripts de Lua pueden ser código fuente o código intermedio compilado. Quizás esté más interesado en el código intermedio compilado, si no desea exponer el código fuente para que todos lo vean.

3. Obtener y configurar variables de Lua

Obtener y configurar el contenido de las variables de script es una función muy básica. LuaTable>("t");

Aquí, el tipo en <> es el tipo de la variable requerida. p>

Lua.Call("print", "Hello World");

int suma = lua.Call("add", 2, 3 );

Aquí, el tipo en <> es el tipo del valor de retorno.

5. Cómo permitir que Lua llame a funciones de C++

Lo siguiente es lo más destacado. Supongamos que tiene una función como esta:

int add(int a, int b)

{

return a + b;

}

Si desea que Lua use esta función, solo necesita registrar la función en el motor de Lua:

lua.RegisterFunc("add", int(int,int ), add);

De esta manera, se puede usar directamente en Lua:

(Lua script) sum = add(1, 3)

(*) La función de RegisterFunc es permitirle registrar funciones de C++ en Lua para su uso en scripts de Lua.

El primer parámetro es el nombre de la función que deseas utilizar en Lua.

El segundo parámetro es el prototipo de la función en C++; C++ permite la sobrecarga de funciones, por lo que puedes usar el prototipo de la función para seleccionar qué función registrar con el motor Lua.

El tercer parámetro es un puntero a una función en C++.

6. Cómo usar clases de C++ en Lua

Comencemos con la siguiente clase de C++:

clase MyArray

{

std::vector array;

public:

void setvalue(int index, double value);

double getvalue (int index);

int size();

const char* ToString();

};

Estás listo Esto permite a Lua acceder y operar libremente esta clase.

Es fácil, sólo agrega algunas definiciones de macro:

class MyArray

{

std::vector array

público:

void setvalue(int index, double value);

double getvalue(int index);

int size();

p>

const char* ToString();

// Es fácil tratar una clase como un objeto Lua, simplemente agregue la siguiente definición de macro.

DEFINE_TYPENAME("My.array");

BEGIN_REGLUALIB("array")

LUALIB_ITEM_create("new", MyArray ) // Crear un MyArray ( Nota: por motivos de publicación, crear debe estar en mayúsculas)

LUALIB_ITEM_DESTROY("del", MyArray ) // Eliminar MyArray.

END_REGLUALIB()

BEGIN_REGLUALIB_MEMBER()

LUALIB_ITEM_FUNC("tamaño",int (MyArray*),&MyArray::size)

LUALIB_ITEM_FUNC("__getindex",double(MyArray*,int),&MyArray:.getvalue)

LUALIB_ITEM_FUNC("__newindex", void (MyArray*, int, double), &MyArray::setvalue)

LUALIB_ITEM_FUNC("__tostring ", const char* (MyArray*), &MyArray::ToString)

LUALIB_ITEM_DESTROY("__gc", MyArray ) // Elimina el objeto para la recolección de basura.

END_REGLUALIB_MEMBER()

};

Con estas macros, esta clase ahora es una clase que se puede usar en Lua y podemos registrarla en Lua. Esta clase:

lua.Register()

Después de registrarnos de esta manera, podemos usar esta clase en Lua:

a = array. new() -- crea un objeto, equivalente a a = new Myarray

a[1] = 10 -- llama a __newindex, equivalente a a->setvalue(1, 10) en C++ -- equivalente a ->size() en C++

a[1], -- llama a __getindex, en C++ es a->getvalue(1)

a[2]) -- Llame a __getindex, en C++ es a->getvalue(2)

array.del(a) -- Borrar el objeto, lo que equivale a eliminar a

a = nil - - borre a, al igual que a = NULL en C++

Por supuesto, también puede esperar a que Lua recolecte basura automáticamente en lugar de profundizar en el objeto.

Cuando Lua realiza la recolección de basura, automáticamente llama a __gc en el objeto, lo que equivale a eliminarlo.

¿Y qué pasa si quieres crear un objeto MyArray en C++ y pasarlo a una variable global de Lua? Como hablamos antes, use SetGlobal:

MyArray* a = new MyArray;

lua.SetGlobal("a", a);

Para obtener un objeto, también debes usar GetGlobal:

MyArray* a = lua .GetGlobal("a");

Para los objetos pasados ​​a Lua, simplemente deja que Lua administre el ciclo de vida del objeto. Si debe eliminar el objeto, puede usar DelGlobalObject:

lua.DelGlobalObject("a");

Pero al hacer esto, debe comprender lo que está haciendo. Qué, porque es posible que se haya hecho referencia al objeto en varios lugares del script Lua. Eliminar una de ellas invalidará las otras referencias, lo que podría provocar un fallo del sistema.

(1) DEFINE_TYPENAME("My.array");

El nombre del tipo definido. En Lua, el nombre del tipo identifica de forma única el tipo C++; debes dar nombres diferentes a diferentes objetos.

(2) BEGIN_REGLUALIB("array") ...END_REGLUALIB()

Puede definir una biblioteca para un objeto, "array" es el nombre de la biblioteca. Las funciones definidas en una biblioteca son funciones globales. En Lua, para usar esta función, debe agregar el nombre de la biblioteca antes de la función, como array.new(). Normalmente, una biblioteca de programas contiene métodos para crear objetos. Por ejemplo:

LUALIB_ITEM_create("new", MyArray) // Crear MyArray (nota: por motivos de publicación, crear debe estar en mayúsculas)

Así es como se crea MyArray en Lua:

a = array.new()

También puede optar por agregar una operación de eliminación de objeto:

LUALIB_ITEM_DESTROY("del", MyArray ) // Eliminar MyArray

De esta manera puedes eliminar un objeto directamente:

array.del(a)

(3) BEGIN _REGLUALIB_MEMBER() ...END_REGLUALIB_MEMBER()

Aquí puede definir las funciones miembro del objeto y sobrecargar los operadores del objeto; sí, al igual que la sobrecarga de operadores de C++. Por ejemplo:

LUALIB_ITEM_FUNC("__newindex", void (MyArray*, int, double), &MyArray::setvalue)

Esta es una sobrecarga del operador [] operador.

Por ejemplo:

__getindex: Operador [], admite acceso de lectura, por ejemplo, v = a[10]

__newindex: Operador [], admite acceso de asignación, por ejemplo, a [10] = 1.22

__tostring: Convierte una variable a una cadena __add: Equivalente a operador+

__add: Operador+

__sub: Operación Operador -

__mul: operador×

__div: operador÷

__pow: operador^ (multiplicación)

__unm: Operador unario-

__concat: Operador (Concatenación de cadenas)

__eq: Operador == (a ~= b es igual a no a == b)

__lt: operador. < (a > b es igual a b < a)

__le: operador <= (a >= b es igual a b <= a, tenga en cuenta que si no está definido "__le", LLM no definirlo. Si "__le" no está definido, Lua intentará convertir a<=b a not (b < a) )

__gc: llamado durante la recolección de basura, equivalente a Destructor en C++. Se recomienda encarecidamente definir este operador para evitar pérdidas de memoria y otras situaciones. Por ejemplo:

LUALIB_ITEM_DESTROY("__gc", MyArray ) // Elimina objetos para la recolección de basura.

(Nota) Lo que hay que tener en cuenta aquí es que en lua, el operador de índice de acceso es __index en lugar de __getindex. En la biblioteca luaWrapper, para facilitar su uso, está asignado a __getindex y _ The. Se ignorará la definición de _index.