25.3 Error Handling with the C API Lua中的数据结构都是动态类型的:按需要增加,自动收缩。这就意味着在内存回收时发生错误是不可避免的。几乎所有的操作都会遇到这个问题。不仅如此,很多操作可能会引发别的错误:例如访问全局变量可能会在元方法__index 中遇到错误。 Lua使用异常机制来抛出错误,而不是在各个API操作中使用具体的错误操作代码。但是,C与C++和Java相比,并没有提供异常处理机制。为了处理这个不同,Lua在应对C的时候使用了setjmp特性,这是一个类似于异常处理机制的特性。因此大多数API函数都能抛出错误(调用 longjmp)而不是直接返回。 当我们使用库代码(此时C函数可以被lua调用),使用long jumps就如同使用异常处理机制般方便,因为Lua可以捕获任何的偶然发生的错误。当我们使用应用代码(application code 此时是C代码调用Lua),我们需要提供捕获这些错误的方法。
Error handing in application code(C调用Lua) 此时为了能合理的处理错误,需要使用Lua来调用代码,也就是说设置一个合理的环境来捕获错误。此时我们也可以使用pcall来安全运行Lua代码,也可以使用lua_pcall来运行C代码。不仅如此,我们也可以用一个函数封装C代码然后用Lua来调用,使用lua_pcall,这样就可以在安全模式下运行C代码了。即便是在内存配置失败的情况下,lua_pcall也能返回一个正确的错误代码,保持运行正常。
Error handing in library code(Lua调用C) Lua是一门安全语言(safe language?).这就意味着无论你写的是什么样的Lua代码,也无论里头有多大的错误,你都能从Lua角度理解到程序做出的反应??不仅如此,错误是从Lua角度来检测和解释的。这个可以和C做对比,看C的错误处理机制是如何的。 无论何时C库中的函数检测到一个错误,都会调用lua_error函数来处理错误,函数会清理lua所有能清理的东西并且会回跳至引发错误的位置并安全执行(jumps back to the protected call that originated that execution),传递出错误信息。