代码之家  ›  专栏  ›  技术社区  ›  Oli

嵌入的lua“print”在Visual Studio的调试模式下不工作

  •  3
  • Oli  · 技术社区  · 15 年前

    我正在使用LuaInterface 2.0.3将Lua嵌入到C应用程序中。

    除了在Visual Studio的调试模式下, 打印 函数不会被写入控制台(也不会被输出)。

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

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

    我错过什么了吗?

    谢谢!

    4 回复  |  直到 14 年前
        1
  •  8
  •   RBerteig Keith Adler    15 年前

    不幸的是,你可能遇到了 print() 函数,它实际上是为了在控制台提示下进行快速而脏的调试,并且缺少一些必要的灵活性。

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

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

    我不知道LuaInterface是如何处理标准C运行时的 标准输出 . 很可能是那样 标准输出 没有连接到任何在vs调试程序中有用的东西,因为它可能利用了一些.NET功能来捕获正在调试的模块的输出,这些输出在任何情况下都可能与C不完全兼容。

    也就是说,很容易取代标准 print 功能。只需使用LuaInterface的现有功能编写一个名为 打印 那个电话 tostring() 在每个参数上,并将其传递给标准输出设备whatever.net。

        2
  •  2
  •   Mark Rushakoff    15 年前

    我没有使用LuaInterface,所以我不能肯定,但您可能想尝试手动调用

    io.output(io.stdout)
    

    看着 Programming in Lua ch 21.1 ,它们解释了如何重定向 print 的输出通过设置io.output进行。也见 IO Library Tutorial .

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

        3
  •  2
  •   Philippe GOETZ    14 年前

    下面是一个代码示例,说明如何使用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;
    }
    

    C中Lua的初始化如下:

    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));
    
        4
  •  1
  •   sth    15 年前

    替换文件“lua/etc/luavs.bat”中的第7行

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

    具有

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

    并使用调试版本的msvcrt重新编译lua。之后,您的输出将按预期进行重定向。

    推荐文章