alienchang 发表于 2013-1-26 12:32:17

Lua C库编程的一些心得

在对Lua语言进行C扩展的时候,注意一个最最重要的就是,关键在于Lua那个栈的管理,对参数的接收和返回都是通过那个栈来实现的,所以一定要深刻理解它的栈管理,有些函数如lua_newuserdata会push到栈上,有些函数会pop如luaL_ref,有些函数只取值并不改变栈状态如luaL_checkstring,随时注意栈状态的变化,这个我们可以用lua_gettop函数来观察栈顶变化来估计栈中的内容,lua和C结合在lua中调试很恶心,只能通过printf来估计
    1、关于Lua接口的导出:
    lua是通过在C DLL中export一个luaopen_LUAMODALNAME函数来实现这个导出的,注意那个LUAMODALNAME是你导出的库名,然后需要做的是在这个函数用luaL_openlib 、luasql_set_info或luaL_register来注册打开要导出的函数,这些函数的第三个参数都是一个类似lua table结果的数组,理解了lua栈的工作原理就知道为什么是这个样子的,示例如下:
extern "C" int LURL_API luaopen_lurl(lua_State* L){      const luaL_Reg mylib[] ={{"escape", escape},{"deescape", deescape},{NULL, NULL}};//lua_register(L, "escape",escape); //使用lua_register注册函数 //lua_register(L, "deescape",deescape); //使用lua_register注册函数 luaL_register(L, "lurl", mylib);return 1;}
   这样在lua中调用require'mylib'时就能打开这个modal了,注意:如果register一个table相当于返回了一个table,然后可以mylib.escape这来调用,而如果register一个函数的话就相当于注册了一个全局函数,直接escape这样调用就行了
LUASQL_API int luaopen_luasql_oci8 (lua_State *L) {struct luaL_reg driver[] = {{"oci8", create_environment},{NULL, NULL},};create_metatables (L);luaL_openlib (L, LUASQL_TABLENAME, driver, 0);luasql_set_info (L);return 1;}
    这样在lua中调用require'luasql.oci8'时就能打开这个modal了(注意放到luasql文件夹里才行),然后调用luasql.oci8()时它就会调用create_environment函数了

    2、关于metatable实现:
    使用luasql_createmeta来创建一个metatable如下:
struct luaL_reg statement_methods[] = {{"close", stmt_close},{"bind_number", stmt_bind_number},{"bind_string", stmt_bind_string},{"bind_cursor", stmt_bind_cursor},{"execute", stmt_execute},{NULL, NULL}};luasql_createmeta (L, LUASQL_STATEMENT_OCI8, statement_methods);

    3、关于userdata实现:
    首先lua_newuserdata来新建一个userdata这时它会把这个结果push到栈顶,然后你可以通过 luasql_setmeta来设置它的metatable,或者直接初始化返回,这时结构已经在栈中,return 1通知lua环境你要返回一个返回值就行

    4、关于table的返回:
    有两种方式:1、用lua_createtable来自己创建一个table2、传入一个空table然后填充然后通过lua_pushvalue复制到栈顶返回(参考luasql中cur_fetch的实现)
填充过程也有两种方式:
    1.)通过void lua_rawseti (lua_State *L, int index, int n);,这种方式是从栈顶淡出value,然后实现t = v 的操作
    2.)通过 lua_rawset 或 lua_settable,这种方式是自定义key的实现,lua先从栈中先弹出key,然后弹出值,实现一个 t = v
页: [1]
查看完整版本: Lua C库编程的一些心得