2009-09-23 13 views
3

J'utilise Luainterface 2.0.3 pour intégrer Lua dans une application C#.Lua "print" ne fonctionne pas en mode débogage à partir de Visual Studio

Tout fonctionne correctement, sauf dans le mode de débogage de Visual Studio, la fonction d'impression de Lua n'est pas écrite sur la console (ni sur la sortie).

using System; 
using LuaInterface; 

namespace Lua1 { 
    class Program { 
     static void Main(string[] args) { 
      Lua lua = new Lua(); 
      lua.DoString("print 'Hello from Lua!'"); 
     } 
    } 
}  

Exécution en mode non de débogage, impression fonctionne bien.

Ai-je raté quelque chose?

Merci!

Répondre

8

Malheureusement, vous êtes probablement confronté à un manque connu dans la fonction print(), qui est vraiment destinée à un débogage rapide et incorrect à l'invite de la console, et il manque une certaine flexibilité nécessaire.

La fonction de bibliothèque de base print() implémentée par luaB_print() in lbaselib.c utilise explicitement le flux stdout de C runtime comme destination. Comme il se réfère explicitement à la variable globale stdout dans son implémentation, la seule façon de le rediriger consiste à rediriger ce descripteur de fichier. Dans un programme C qui peut être fait en appelant freopen(stdout,...). Malheureusement, il n'y a pas de fonction de bibliothèque de stock dans Lua qui puisse le faire. La bibliothèque io est implémentée en liolib.c. Il utilise l'environnement de fonction pour contenir une table de descripteurs de fichier ouverts, et lors de son initialisation il crée file objets nommés io.stdin, io.stdout et io.stderr pour les trois descripteurs standard. Il fournit également des fonctions nommées io.output et io.input pour permettre à ces deux descripteurs d'être modifiés pour pointer vers un objet file ouvert (ou un fichier nouvellement ouvert si un nom de fichier est passé). Toutefois, ces fonctions modifient uniquement la table d'environnement de fonction et n'appellent pas freopen() pour modifier la table FILE du tableau d'exécution C.

Je ne sais pas comment LuaInterface tente de traiter l'idée du runtime C standard de stdout. Il se peut très bien que stdout ne soit pas connecté à quelque chose d'utile dans le débogueur VS car il profite probablement d'une fonctionnalité .NET pour capturer la sortie du module en cours de débogage qui n'est peut-être pas tout compatible avec C dans tous les cas. Cela dit, il est facile de remplacer la fonction print standard. Il suffit d'utiliser les fonctions existantes de LuaInterface pour écrire une fonction globale nommée print qui appelle tostring() sur chaque argument et le transmet à n'importe quel objet .NET est le périphérique de sortie standard.

2

Je ne l'ai pas utilisé LuaInterface, donc je ne peux pas dire à coup sûr, mais vous pouvez essayer d'appeler manuellement

io.output(io.stdout) 

En regardant Programming in Lua ch 21.1, ils expliquent comment vous pouvez rediriger la sortie où l » print passe en définissant io.output. Voir aussi le IO Library Tutorial. Je ne suis pas sûr si cela résoudra réellement le problème, cependant, car je ne peux pas trouver quelque chose lié à io.output étant défini dans the LuaInterface source on Google Code.

1

Remplacer la ligne 7 dans le fichier "lua/etc/luavs.bat"

@set MYCOMPILE=cl /nologo /MD /O2 /W3 /c /D_CRT_SECURE_NO_DEPRECATE 

avec

@set MYCOMPILE=cl /nologo /MDd /Od /W3 /c /D_CRT_SECURE_NO_DEPRECATE 

et recompiler lua avec la version de débogage de MSVCRT. Après cela, votre sortie sera redirigée comme prévu.

2

Voici un exemple de code comment utiliser la classe LuaDLL utilisée dans le LuaInterface pour rediriger la fonction d'impression lua:

// See http://medek.wordpress.com/2009/02/03/wrapping-lua-errors-and-print-function/ 
static int LuaPrint(IntPtr L) 
{ 
    int nArgs = LuaDLL.lua_gettop(L); 
    LuaDLL.lua_getglobal(L, "tostring"); 
    string ret = ""; //this is where we will dump the output 
    //make sure you start at 1 *NOT* 0 
    for(int i = 1; i <= nArgs; i++) 
    { 
     LuaDLL.lua_pushvalue(L, -1); 
     LuaDLL.lua_pushvalue(L, i); 
     LuaDLL.lua_call(L, 1, 1); 
     string s = LuaDLL.lua_tostring(L, -1); 
     if(s == null) 
      return LuaDLL.luaL_error(L, "\"tostring\" must return a string to \"print\""); 
     if(i > 1) ret += "\t"; 
     ret += s; 
     LuaDLL.lua_pop(L, 1); 
    }; 
    //Send it wherever 
    Console.Out.WriteLine(ret); 
    return 0; 
} 

L'initialisation de lua en C# ressembler à:

IntPtr luaState = LuaDLL.luaL_newstate(); 
LuaDLL.luaL_openlibs(luaState); 
LuaDLL.lua_newtable(luaState); 
LuaDLL.lua_setglobal(luaState, "luanet"); 
Lua l = new Lua(luaState.ToInt64()); 
LuaDLL.lua_register(luaState, "print", new LuaCSFunction(LuaPrint));