3

我正在使用 Luainterface 2.0.3 将 Lua 嵌入到 ac# 应用程序中。

一切正常,除了在 Visual Studio 的调试模式下,Lua 的打印功能不会写入控制台(也不会写入输出)。

using System;
using LuaInterface;

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

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

我错过了什么吗?

谢谢!

4

4 回答 4

8

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

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

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

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

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

于 2009-09-23T22:09:29.020 回答
3

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

io.output(io.stdout)

查看Lua ch 21.1 中的 Programming,他们解释了如何print通过设置 io.output 来重定向 where 的输出。另请参阅IO 库教程

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

于 2009-09-23T16:29:21.243 回答
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;
}

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));
于 2010-12-01T02:52:19.280 回答
1

替换文件“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。之后,您的输出将按预期重定向。

于 2010-07-09T17:36:28.123 回答