2009-09-23 104 views
3

我正在使用Luainterface 2.0.3将Lua嵌入到c#应用程序中。嵌入式Lua“print”不能在Visual Studio的调试模式下工作

一切工作正常,除了在Visual Studio的调试模式下,Lua的print函数没有写入控制台(也不输出)。

using System; 
using LuaInterface; 

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

在非调试模式下运行它,打印工作正常。

我错过了什么吗?

谢谢!

回答

8

不幸的是,您可能已经遇到print()函数中的一个已知缺陷,该函数实际上是用于在控制台提示符下进行快速和肮脏的调试,并且缺少一些必要的灵活性。

luaB_print() in lbaselib.c实现的基本库函数print()明确使用C运行时的stdout流作为其目标。由于它在其实现中显式引用了全局变量stdout,因此重定向它的唯一方法是使该文件句柄被重定向。在C程序中可以通过调用freopen(stdout,...)来完成。不幸的是,Lua中没有库存函数可以做到这一点。

io库在liolib.c中实现。它使用功能环境来保存打开文件描述符的表格,并且在其初始化期间,它为三个标准描述符创建名称为io.stdinio.stdoutio.stderr的对象file。它还提供名为io.outputio.input的函数,允许修改这两个描述符以指向任何打开的对象(如果传递文件名,则为新打开的文件)。但是,这些函数只会更改函数环境表,并且不要调用freopen()来修改C运行时的FILE值表。

我不知道LuaInterface如何试图处理标准C运行时的想法stdout。很可能stdout没有连接到VS调试器中任何有用的东西,因为它可能利用了某些.NET功能来捕获正在调试的模块的输出,在任何情况下都可能与C不兼容。

这就是说,很容易替换标准的print函数。只需使用LuaInterface的现有功能编写一个名为print的全局函数,该函数在每个参数上调用tostring()并将它传递给任何.NET事物是标准输出设备。

2

我没有用过LuaInterface,所以我不能肯定地说,但你可能想尝试手动调用

io.output(io.stdout) 

看着Programming in Lua ch 21.1,他们解释如何重定向哪里print的输出通过设置io.output。另请参阅IO Library Tutorial

但是,我不确定这是否会真正解决问题,因为我找不到任何与the LuaInterface source on Google Code中设置的io.output相关的任何内容。

1

文件 “LUA的/ etc/luavs.bat”

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

替换线7

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

与MSVCRT的调试版本重新编译LUA。之后,您的输出将按预期重定向。

2

下面一个代码示例如何使用在LuaInterface使用的LuaDLL类重定向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; 
} 

LUA的C#中的初始化是这样的:

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)); 
相关问题