[英]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.stdin
, io.stdout
和io.stderr
file
对象。 它还提供了名为io.output
和io.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.