2010-12-22 15 views
13
incrustado

He incrustado Lua en mi aplicación C++. Quiero redirigir las declaraciones de impresión (o tal vez simplemente redefinir la función de impresión?), Para que pueda mostrar la expresión evaluada en otro lugar.Redireccionando/redefiniendo print() para Lua

¿Cuál es la mejor manera de hacer esto: redirigir o redefinir la función print()?

Cualquier fragmento o puntero a los fragmentos que muestren cómo hacerlo sería muy apreciado.

Respuesta

4

Ver luaB_print en lbaselib.c. El comentario allí dice:

/* If you need, you can define your own `print' function, following this 
model but changing `fputs' to put the strings at a proper place (a 
console window or a log file, for instance). */ 

Puede simplemente editar esa función o definir una nueva. Esto tiene la ventaja de ser simple y portátil, pero no será compatible con io.write (que puede o no preocuparse).

Redirigir IO no va a ser plataforma específica (como SetStdHandle en Windows), pero se hará cargo de printio.write y sin redefinir tampoco.

+0

Eso parece sugerir la modificación directa de las fuentes de Lua (puedo estar equivocado), pero seguramente, ¿debe haber una forma mejor? – skyeagle

+0

Bueno, no tengo una particular aversión a editar la fuente Lua, siempre y cuando no cambie la semántica de nada. Escribí un "compilador" de Lua que vinculaba los archivos al EXE como recursos, y luego enganché las rutinas de archivos de Lua para leer de los recursos ejecutables en lugar del sistema de archivos. Solo tuvo que cambiar algunas líneas de fuente. No puedo imaginarme qué pesadilla hubiera sido si hubiese intentado evitar esos cambios. – Mud

+0

La solución que Mike M da no toca el código Lua. Proporciona una función de impresión personalizada y anula la predeterminada al registrarla a través de la función Lua C 'lua_register (L," print ", my_print)'. –

2

Escriba su propia función C o Lua y redefina print.

10

Simplemente puede redefinir la impresión desde un script Lua.

local oldprint = print 
print = function(...) 
    oldprint("In ur print!"); 
    oldprint(...); 
end 
22

Puede redefinir la sentencia de impresión en C:

static int l_my_print(lua_State* L) { 
    int nargs = lua_gettop(L); 

    for (int i=1; i <= nargs; i++) { 
     if (lua_isstring(L, i)) { 
      /* Pop the next arg using lua_tostring(L, i) and do your print */ 
     } 
     else { 
     /* Do something with non-strings if you like */ 
     } 
    } 

    return 0; 
} 

continuación, se registra en la tabla global:

static const struct luaL_Reg printlib [] = { 
    {"print", l_my_print}, 
    {NULL, NULL} /* end of array */ 
}; 

extern int luaopen_luamylib(lua_State *L) 
{ 
    lua_getglobal(L, "_G"); 
    // luaL_register(L, NULL, printlib); // for Lua versions < 5.2 
    luaL_setfuncs(L, printlib, 0); // for Lua versions 5.2 or greater 
    lua_pop(L, 1); 
} 

Puesto que usted está usando C++ tendrá que incluir su archivo usando 'extern "C"'

+0

Funciona bastante bien. Muchas gracias ! –

+0

@MikeM. ¿Hay alguna manera, así que úsala para llamar a 'luaL_dostring' simplemente devuelve la salida requerida como' char * '? – ewok

+0

+1! exactamente lo que necesitaba @ewok, luaL_dostring devuelve un const char * para que tenga exactamente lo que necesita. –

1

Puede simplemente redefinir las siguientes macros:

lua_writestring 
lua_writeline 
lua_writestringerror 

a lo que quieras. No estoy seguro acerca de la versión de lua donde se introdujo esto, pero funciona en 5.3 para mí.

Compruebe su lauxlib.h o luaconf.h.