2011-01-28 12 views
6

Quiero que los usuarios de mi aplicación C++ puedan proporcionar funciones anónimas para realizar pequeños fragmentos de trabajo.¿Cómo puedo cargar una función sin nombre en Lua?

Pequeños fragmentos como este serían ideales.

function(arg) return arg*5 end 

Ahora me gustaría ser capaz de escribir algo tan simple como esto para mi código C,

// Push the function onto the lua stack 
lua_xxx(L, "function(arg) return arg*5 end") 
// Store it away for later 
int reg_index = luaL_ref(L, LUA_REGISTRY_INDEX); 

Sin embargo, no creo lua_loadstring va a hacer "lo correcto".

¿Me queda lo que siento como un horrible truco?

void push_lua_function_from_string(lua_State * L, std::string code) 
{ 
    // Wrap our string so that we can get something useful for luaL_loadstring 
    std::string wrapped_code = "return "+code; 
    luaL_loadstring(L, wrapped_code.c_str()); 
    lua_pcall(L, 0, 1, 0); 
} 

push_lua_function_from_string(L, "function(arg) return arg*5 end"); 
int reg_index = luaL_ref(L, LUA_REGISTRY_INDEX); 

¿Existe una solución mejor?

Respuesta

7

Si necesita acceder a los parámetros, la forma en que ha escrito es correcta. lua_loadstring devuelve una función que representa el fragmento/código que está compilando. Si realmente desea obtener una función del código, tiene que return. También hago esto (en Lua) para pequeños "evaluadores de expresiones", y no lo considero un "truco horrible" :)

Si solo necesitas algunas devoluciones de llamada, sin ningún parámetro, puedes escribir el código directamente y use la función devuelta por lua_tostring. Incluso puede pasar parámetros a este fragmento, será accesible como la expresión .... A continuación, puede obtener los parámetros como:

local arg1, arg2 = ... 
-- rest of code 

a decidir qué es mejor para usted - "código feo" dentro de su biblioteca de código base, o "código feo" en sus funciones Lua.

+0

También he decidido que no es tan hacky como mi instinto me sugirió. Y como los usuarios finales van a escribir las funciones lua, creo que mi "no tan horrible" hack es el único camino a seguir. –

+0

Michal tiene razón. El "trozo" puede aceptar argumentos pero necesita la devolución. – mlepage

3

Eche un vistazo a mi ae. Guarda en caché las funciones de las expresiones para que simplemente diga ae_eval("a*x^2+b*x+c") y solo lo compilará una vez.

Cuestiones relacionadas