lua C API
来源:互联网 发布:哪个网站有卖淘宝小号 编辑:程序博客网 时间:2024/05/16 12:44
1: lua_pcall 、 lua_call 、 lua_cpcall
与lua_call相对应的是lua_pcall函数,lua_pcall会以保护模式调用栈中的函数。以保护模式调用意思是,当被调用的函数发生任何错误时,该错误不会传播,不像lua_call会把错误传递到上一层(发生longjmp调用),lua_pcall所调用的栈中函数发生错误时,lua_pcall会捕捉这个错误,并向栈中压入一个错误信息,并返回一个错误码。在应用程序中编写主函数时,应该使用lua_pcall来调用栈中的函数,捕获所有错误。而在为Lua编写扩展的C函数时,应该调用lua_call,把错误返回到脚本层。
lua_cpcall和lua_pcall类似,都是在应用程序中编写主函数时使用,都会捕获错误,向栈中压入一个错误信息,并返回一个错误码;只不过lua_cpcall调用的是c函数.参考luaproc项目。
在lua的世界里, 什么是保护模式和非保护模式呢?这个问题得从Lua错误处理方式说起,c语言对程序里出现的异常错误处理方式是
使用了setjmp和longjmp两个非局部跳转函数来处理。setjmp函数用来设置异常错误发生时,程序的返回点,类似于try;longjmp函数用于
抛出异常错误,类似于throw。在lapi.c文件里查看lua_call和lua_pcall两个API的实现发现:lua_call会调用longjmp, lua_pcall不调用
longjmp;lua_pcall在错误发生时的处理方式是给虚拟栈压入错误信息,并将lua解释器封固在一致的状态。lua_call在错误发生时,会调用
longjmp抛出异常,然后程序跳转到lua解释器的setjmp出,lua解释器捕获错误。所以在为Lua编写c函数库时,应该使用lua_call ;而在编写
应用程序的主函数时,使用lua_pcall。
static void openlibs( lua_State *L ) {
lua_cpcall( L, luaopen_base, NULL );
lua_cpcall( L, luaopen_package, NULL );
registerlib( L, "io", luaopen_io );
registerlib( L, "os", luaopen_os );
registerlib( L, "table", luaopen_table );
registerlib( L, "string", luaopen_string );
registerlib( L, "math", luaopen_math );
registerlib( L, "debug", luaopen_debug );
}
2: lua_error 、 luaL_error、 lua_atpanic
这三个API是用于在c/c++处理lua错误
每一个C程序都有他自己的错勿处理方式,当你打算为Lua写一个库函数的时候,这里有一些标准的处理错误的方法可以参考。不论什么时候,C函数发现错误只要简单的调用lua_error(或者luaL_error,后者更好,因为她调用了前者并格式化了错误信息)。Lua_error函数会清理所有在Lua中需要被清理的,然后和错误信息一起回到最初的执行lua_pcall的地方。具体如何使用可以参考rings库
c/c++在处理lua错误分两种情形:
第一:应用程序中的错误处理,分两种,设置panic函数或者使用lua_pcall调用
典型的情况是应用的代码运行在非保护模式下。由于应用的代码不是被Lua调用的,Lua根据上下文情况来捕捉错误的发生(也就是说,Lua不
能调用setjmp)。在这些情况下,当Lua遇到像 "not enough memory" 的错误,他不知道如何处理。他只能调用一个panic函数退出应用。(你可以
使用lua_atpanic函数设置你自己的panic函数)
在错误发生时,如果你不想你的应用退出,即使在内存分配失败的情况下,你必须在保护模式下运行你的代码。大部分或者所有你的Lua代码
通过调用lua_pcall来运行,所以,它运行在保护模式下。即使在内存分配失败的情况下,lua_pcall也返回一个错误代码,使得lua解释器处于和谐
的(consistent)状态。如果你也想保护所有你的与Lua交互的C代码,你可以使用lua_cpcall
第二:库中的错误处理
当你打算为Lua写一个库函数的时候,这里有一些标准的处理错误的方法可以参考。不论什么时候,C函数发现错误只要简单
的调用lua_error(或者luaL_error,后者更好,因为她调用了前者并格式化了错误信息)。Lua_error函数会清理所有在Lua中需要被清理
的,然后和错误信息一起回到最初的执行lua_pcall的地方
3: lua_getfield 、lua_gettable
lua_getfield(L, -1, key) 于以下两行的效果一样
lua_pushstring(L, key);
lua_gettable(L, -1)
4: lua_setfield 、 lua_settable
lua_pushstring(L, key)
lua_pushnumber(L, value)
lua_settable(L, -3)
以上三行的效果等同于以下两行
lua_pushnumber(L, value)
lua_setfield(L, -2, key)
5:lua_setglobal 、lua_getglobal
static int l_sin (lua_State *L) {
double d = lua_tonumber(L, 1); /* get argument */
lua_pushnumber(L, sin(d)); /* push result */
return 1; /* number of results */
}
lua_pushcfunction(l, l_sin); /*将类型为fC函数的值l_sin入栈 */
lua_setglobal(l, "mysin"); /* 将C函数l_sin赋值给lua全局变量mysin */
比如lua配置文件有如下lua函数
function func(x, y)
return (x^2 * math.sin(y))/(1 - x)
end
那么可以在c中调用lua函数func
lua_getglobal(L, "func"); /* function to be called */
lua_pushnumber(L, 1,); /* push 1st argument */
lua_pushnumber(L, 2); /* push 2nd argument */
lua_pcall(L, 2, 1, 0) != 0)
6:lua_isXXXX 、lua_toXXX 、 luaL_checkXXX、 lua_type、lua_typename
lua_is*函数来检查一个元素是否是一个指定的类型,*可以是任何Lua类型。lua_isnumber和lua_isstring函数不检查这个值是否是指定的类型,而是看它是否能被转换成指定的那种类型。例如,任何数字类型都满足lua_isstring。
为了从栈中获得值,这里有lua_to*函数:
int lua_toboolean (lua_State *L, int index);
double lua_tonumber (lua_State *L, int index);
const char * lua_tostring (lua_State *L, int index);
size_t lua_strlen (lua_State *L, int index);
即使给定的元素的类型不正确,调用上面这些函数也没有什么问题。在这种情况下,lua_toboolean、lua_tonumber和lua_strlen返回0,其他函数返回NULL。由于ANSI C没有提供有效的可以用来判断错误发生数字值,所以返回的0是没有什么用处的。对于其他函数而言,我们一般不需要使用对应的lua_is*函数:我们只需要调用lua_is*,测试返回结果是否为NULL即可。
Lua_tostring函数返回一个指向字符串的内部拷贝的指针。你不能修改它(使你想起那里有一个const)。只要这个指针对应的值还在栈内,Lua会保证这个指针一直有效。当一个C函数返回后,Lua会清理他的栈,所以,有一个原则:永远不要将指向Lua字符串的指针保存到访问他们的外部函数中。
辅助库中的luaL_checkXXX函数可以检查参数类型是否正确,如果类型不正确,它会抛出一个错误消息,反之,返回该类型的值。lua_type函数,它返回栈中元素的类型。(lua_is*中的有些函数实际上是用了这个函数定义的宏)在lua.h头文件中,每种类型都被定义为一个常量:LUA_TNIL、LUA_TBOOLEAN、LUA_TNUMBER、LUA_TSTRING、LUA_TTABLE、LUA_TFUNCTION、LUA_TUSERDATA以及LUA_TTHREAD。
7:lua_rawget、lua_rawset、lua_rawgeti、lua_rawseti
出于性能考虑,即绕过元表metatable; 为数组操作提供了lua_rawgeti,luarawseti两个C API函数。
void lua_rawgeti (lua_State *L, int index, int key);
void lua_rawseti (lua_State *L, int index, int key);
index指向table在栈中的位置;key指向元素在table中的位置。
8:luaL_checkXXX、luaL_checkany
luaL_checkXXX类函数用于错误判断,判断lua传递给C的数据是否合法,如果非法会抛出错误。常规的c编程中,错误判断往往是if(xxx) errorLog(...)方式处理,而在lua于C交互的时候,是使用luaL_checkXXX判断。
- lua c api
- LUA C API
- lua C Api 简介
- lua-C API
- 【Lua】C-API
- lua C API
- LUA C API接口
- C++ – Lua C API
- lua的c api 总结
- lua的c api 总结
- lua(7)-C API
- 导出C/C++API给Lua使用
- LUA中C API的熟悉实例
- Lua 学习笔记:C API 遍历 Table
- Lua 学习笔记:C API 遍历 Table
- 导出 C/C++ API 给 Lua 使用
- Step By Step(Lua-C API简介)
- lua 与的C api交互操作
- 图像边缘检测原理&何谓角点及Harris角点的基本原理&SURF特征提取简介
- 所有的经历都是为了更好的前行
- int、bigint、smallint 和 tinyint范围
- django-CBVS (转载知乎彧神)
- 7.1 方法
- lua C API
- Java NIO系列教程(四) Scatter/Gather
- 9.Selenium2 自动化测试实战-基于Python语言-键盘事件
- 剑指offer-树的子结构
- RTP Payload H264
- C#中引用传递与指针传递区别
- 关于资源文件R
- HDU 2433 Travel
- java进入Catalina步骤查看引擎VxBPEL部署的工程以及对VxBPEL工程进行配置