如何从 Lua 中调用可以抛出异常的 C# 委托
2021-9-1 12:39:58
收藏:0
阅读:149
评论:1
在基于 Linux 的 Docker 镜像中运行以下代码会导致 CLR 崩溃。
static void Main(string[] args)
{
System.Console.WriteLine("程序开始");
using (NLua.Lua luaState = new NLua.Lua())
{
System.Action invoke = () => throw new System.Exception("异常信息");
luaState["invoke"] = invoke;
try
{
System.Console.WriteLine("执行委托");
luaState.DoString(@"invoke()");
}
catch (System.Exception ex)
{
// 不会执行到这里
System.Console.WriteLine("捕获到异常");
throw;
}
}
}
我做错了什么吗?
Dockerfile 是 Visual Studio 提供的默认建议,并且是从 Visual Studio 启动的进程。
在 Docker 外部运行程序,即在 Windows 主机上运行,结果是符合预期的。(执行到 catch 语句并且不会导致 CLR 出现致命错误。)
将委托包装在“pcall”中不能解决该问题。
可以通过注册函数而不是发送委托来避免该问题。 如果委托不抛出异常,则按预期调用它。
镜像的控制台日志如下:
程序开始
执行委托
Unhandled exception. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.Exception: 异常信息
at LuaTest.Program.<>c.<Main>b__0_0() in C:\Source\Tests\LuaTest\Program.cs:line 10
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at NLua.MetaFunctions.CallDelegateInternal(Lua luaState)
at NLua.MetaFunctions.CallDelegate(IntPtr state)
at KeraLua.NativeMethods.lua_pcallk(IntPtr luaState, Int32 nargs, Int32 nresults, Int32 errorfunc, IntPtr ctx, IntPtr k)
at KeraLua.Lua.PCall(Int32 arguments, Int32 results, Int32 errorFunctionIndex)
at NLua.Lua.DoString(String chunk, String chunkName)
at LuaTest.Program.Main(String[] args) in C:\Source\Tests\LuaTest\Program.cs:line 15
Fatal error. Internal CLR error. (0x80131506)
at KeraLua.NativeMethods.lua_pcallk(IntPtr, Int32, Int32, Int32, IntPtr, IntPtr)
at KeraLua.NativeMethods.lua_pcallk(IntPtr, Int32, Int32, Int32, IntPtr, IntPtr)
at KeraLua.Lua.PCall(Int32, Int32, Int32)
at NLua.Lua.DoString(System.String, System.String)
at LuaTest.Program.Main(System.String[])
原文链接 https://stackoverflow.com/questions/69013446
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在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 模式将字符串(嵌套数组)转换为真正的数组?
这似乎是 NLua 中
MetaFunctions.CallDelegate
的一个 bug。委托的调用没有在 try-catch 块中。与LuaMethodWrapper.Call
相比。致命错误可能是由于尝试通过调用 longjmp 的非托管代码来传播异常所致。请参见 dotnet core 关于异常互操作性的笔记。
最直接的解决方法是使用 register function 注册委托:
Action action=()=>throw new Exception() luastate.RegisterFunction("invoke",action.Target,action.Method);