Anuncios

Bienvenidos sean a este post, continuaremos con lo visto en los posts anteriores y hoy hablaremos sobre una de las grandes fuerzas de Lua como es que un archivo de configuracion puede definir funciones para ser llamada por aplicaciones.

Anuncios

Por ejemplo podemos escribir una aplicacion para trazar el grafico de una funcion y usar a Lua para definir la funcion a ser trazada, el protocolo de API para llamar a una funcion es simple:

  • primero, empujas la funcion a ser llamada
  • segundo, empujas los argumentos a la llamada
  • por ultimo, quitas los resultados de la pila
Anuncios

Asumamos que tenemos la siguiente funcion en nuestro archivo de configuracion:

function f(x, y)
	return(x^2 * math.sin(y))/(1 - x)
end
Anuncios

Si quieres evaluar en C a z = f(x, y) para unos valores dados de x e y, tambien asumiendo que ya has abierto la libreria de Lua y corres el archivo de configuracion, podemos encapsular esta llamada en la siguiente funcion de C:

double f(double x, double y)
{
	double z;
	
	lua_getglobal(L, "f");
	lua_pushnumber(L, x);
	lua_pushnumber(L, y);

	if (lua_pcall(L, 2, 1, 0) != 0)
		error(L, "error corriendo la funcion 'f': %s",
			lua_tostring(L, -1));
	
	if (!lua_isnumber(L, -1))
		error(L, "la funcion 'f' debe retornar un numero");
	z = lua_tonumber(L, -1);
	lua_pop(L, 1);
	return z;
}
Anuncios

Llamamos a lua_pcall con el numero de argumentos que estas pasando y el numero de resultados que quieres, el cuarto argumento indica una funcion de manejo de error, de esto hablaremos en otro momento.

Anuncios
Anuncios

Como una asignacion en Lua, lua_pcall ajusta el numero actual de resultados a los que pediste, empujando nils o descartar valores extras segun sea necesario, antes de empujar los resultados lua_pcall remueve de la pila a la funcion y los argumentos, si la funcion devuelve multiples resultados: el primer resultado es empujado primero; por ejemplo si hay tres resultados; el primero tendra un indice de -3 y el ultimo de -1, si hay algun error durante la ejecucion de lua_pcall, esta devuelve un valor distinto de cero ademas empuja el mensaje de error en la pila pero aun asi quita la funcion y los argumentos, antes de empujar el mensaje lua_pcall llama a la funcion manipuladora de error si existe alguno. Para especificar una funcion de manejo de errores usamos el ultimo argumento de lua_pcall, un cero significa que no hay ninguna funcion de manejo de error, es decir que el mensaje final de error es el mensaje original, de lo contrario este argumento debera ser el indice en la pila donde la funcion manejadora de error esta ubicado, en tales casos el manejador debe ser empujado en la pila en algun lugar por debajo de la funcion que sera llamada y sus argumentos, para errores normales lua_pcall devuelve el codigo de error LUA_ERRRUN.

Anuncios

Hay dos tipos especiales de errores que reciben codigos diferentes porque ellos nunca corren en el manejador de errores; el primer tipo es un error de ubicacion de memoria y para tales errores lua_pcall siempre devuelve LUA_ERRMEM; el segundo tipo es un error mientra Lua esta corriendo el manejador de errores mismo, en este caso es de poco uso llamar al manejador de error de nuevo asi que lua_pcall regresa inmediatamente con un codigo LUA_ERRERR.

Anuncios

En resumen, hoy hemos visto de forma simple como se llama a una funcion Lua desde un programa de C, como encapsular dicha funcion, como intercambiamos informacion con la pila y los manejadores de error con sus respectivas salidas, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios

Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00