繁体   English   中英

嵌入式Lua“打印”在Visual Studio中无法在调试模式下工作

[英]Embedded Lua “print” not working in debug mode from Visual Studio

我正在使用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!'");
       }
    }
}    

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

我错过了什么吗?

谢谢!

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

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

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

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

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

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

io.output(io.stdout)

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

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

这里的代码示例如何使用LuaInterface中使用的LuaDLL类重定向lua print函数:

// 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));

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM