使用NLua在C# WinForms中修改主窗体位置时遇Lua脚本异常
解决NLua脚本中设置WinForms窗体Location的问题
你的问题出在NLua对CLR类型的引用方式上,直接使用Point或System.Drawing.Point不符合NLua的CLR交互规则,以下是几种可行的解决方案:
方案1:使用clr全局表直接引用CLR类型
NLua加载CLR包后会自动创建clr全局表,所有CLR类型都可以通过clr.命名空间.类型的方式访问,直接调用构造函数创建实例:
lua_context.DoString("main_form.Location = clr.System.Drawing.Point(5, 5)");
方案2:结合import和new关键字实例化对象
import指令会将指定命名空间下的类型导入Lua环境,但需要用new关键字触发CLR对象的实例化(Lua本身没有构造函数概念,NLua通过new模拟):
// 已执行过 import 'System.Drawing' 的前提下 lua_context.DoString("main_form.Location = new Point(5, 5)");
方案3:在C#中注册Point类型到Lua全局变量
直接将System.Drawing.Point的Type对象注册到Lua上下文,这样Lua脚本可以直接调用构造函数:
// 在设置main_form之后添加 lua_context["Point"] = typeof(System.Drawing.Point); // 之后Lua脚本即可直接使用 lua_context.DoString("main_form.Location = Point(5, 5)");
完整修正代码示例
以下是使用方案2的完整可运行代码:
using NLua; using System.Windows.Forms; var lua_context = new Lua(); lua_context.LoadCLRPackage(); lua_context.DoString("import 'System.Drawing'"); lua_context.DoString("import 'System.Windows.Forms'"); MainForm main_form = new MainForm(); lua_context["main_form"] = main_form; lua_context.DoString("main_form.Location = new Point(5, 5)"); Application.Run(main_form);
失败原因说明
- 直接使用
Point(5,5):NLua无法识别这是CLR对象构造调用,即使已import命名空间,也需要new关键字触发实例化逻辑。 - 使用
System.Drawing.Point(5,5):NLua的import指令不会创建System这类层级式的全局命名空间对象,因此System是nil,导致索引错误。
内容的提问来源于stack exchange,提问作者sloopy
相关产品推荐
相关产品推荐

