从Visual Studio调试模式中无法使用嵌入式Lua中的"print"函数。
我正在使用Luainterface 2.0.3将Lua嵌入到C#应用程序中。
一切都正常工作,但是在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!'");
}
}
}
在非调试模式下运行,_print_正常工作。
我错过了什么吗?
谢谢!
原文链接 https://stackoverflow.com/questions/1466064
很不幸,你可能已经遇到了 print()
函数中众所周知的缺陷,这个函数实际上是用来快速粗略地调试控制台命令行的,并且缺少一些必要的灵活性。
Lua 基础库函数 print()
是由 lbaselib.c
中的 luaB_print()
实现的,它明确使用 C 运行时的 stdout
流作为其目标输出。由于它在实现中明确引用了全局变量 stdout
,因此唯一重新定向它的方法是使该文件句柄被重新定向。在 C 程序中,这可以通过调用 freopen(stdout,...)
来实现。不幸的是,在 Lua 中没有一个内置库函数可以做到这一点。
io
库是在 liolib.c 中实现的。它使用函数环境来存储已打开文件描述符的表,在初始化期间,它为三个标准描述符创建了名为 io.stdin
、io.stdout
和 io.stderr
的 file
对象。它还提供了名为 io.input
和 io.output
的函数,以允许这两个描述符被修改以指向任何打开的 file
对象(或者如果传递了文件名,则指向一个新打开的文件)。然而,这些函数只会改变函数环境表,并不会调用 freopen()
来修改 C 运行时的 FILE
值表。
我不知道 LuaInterface 是如何处理标准 C 运行时中的 stdout
概念的。很可能,stdout
没有连接到 VS 调试器中的任何有用内容,因为它可能利用了某些 .NET 特性来捕获从调试的模块中产生的输出,而这些特性可能在任何情况下都与 C 不太兼容。
尽管如此,很容易替换标准的 print
函数。只需使用 LuaInterface 的现有功能编写一个名为 print
的全局函数,该函数对每个参数调用 tostring()
,并将其传递给任何 .NET 所使用的标准输出设备。
将文件 "lua/etc/luavs.bat" 中的第 7 行替换为:
@set MYCOMPILE=cl /nologo /MDd /Od /W3 /c /D_CRT_SECURE_NO_DEPRECATE
然后使用 MSVCRT 的 Debug 版本重新编译 lua。之后你的输出将被正确地重定向。
下面是如何使用 LuaDLL 类的代码示例,该类被用于重定向 LuaInterface 中的 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));
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
我没有使用过 LuaInterface,所以不能确定,但是你可能想尝试手动调用
io.output(io.stdout)
查看《Lua 程序设计》第21.1章,它们解释了如何通过设置 io.output 来重定向
print
的输出位置。还可以参考IO库教程。然而,我不确定这是否能真正解决问题,因为我在 Google Code 上的 LuaInterface 源码中找不到任何与设置 io.output 相关的内容。