您的位置:首页 > 编程语言 > Lua

lua和C交互框架

2010-01-28 16:19 281 查看
1、错误(err_return)的宏定义
#define err_return(num,fmt,args) /
do
{
printf("[%s:%d]"fmt"/n",__FILE__,__LINE__,##args);return(num);
} while(0)

-1 是return的返回值,表示有错误;
fmt 是一个字符串,用于打印错误信息;
args表示参数的个数;--这个有疑问,__FILE__,__LINE__,##args 是什么意思?
另外: while(0)是什么意思,什么条件下可以退出?
具体调用实例:err_return(-1,"luaL_newstat() failed",1);

补充解释:

//__FILE__ 进行编译的源文件名
//__LINE__ 文件当前有的行号(注意:是"当前")
//__DATE__ 文件被编译的日期
//__TIME__ 文件被编译的时间
##是字符拼接
像这样
  在#define中,标准只定义了#和##两种操作。#用来把参数转换成字符串,##则用来连接两个前后两个参数,把它们变成一个字符串。 eg.ab##cd 就是abcd, m##1 就是m1;

另外: while(0)是什么意思,什么条件下可以退出?

直接退出,0为false

0是false所以只执行一次do就退出了

while()循环进入的条件是,条件为TRUE,因为0是FALSE,所以循环一次就退出;

do~while() 循环执行一次do里面的内容然后退出,如果直接是while()循环,则不会进入循环体;

2、在lua中调用C函数:
(1)C中写好lua要调用的函数

//lua中要调用的c函数定义,实现加法
int csum(lua_State* l) //定义函数,函数参数是lua_State* l,这也是每个lua要调用的C函数的写法;
{
int a = lua_tointeger(l,1) ; //lua_tointeger()获得整型返回值,一般是把lua传进去的数值(参数或者全局变量)转换成整形;
int b = lua_tointeger(l,2) ; //这里是指第二个参数,被转化成整形;
lua_pushinteger(l,a+b) ; //lua_pushinteger()这里是把返回值(a+b)压入栈
return 1 ; //返回值的数量;
}
可见,lua调用C函数,首先是要写好C中的函数的,首先把函数参数转化成想要的类型,然后把返回值表达式压入栈;
(2)C中写好注册函数,一般是下面的两个:
lua_pushcfunction(l,csum) ; //注册在lua中使用的c函数
lua_setglobal(l,"csum") ; //绑定到lua中的名字csum
也可以使用:
lua_register(l,"csum",csum);
因为:
#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))

(3)C调用lua函数
这里分步进行分析:
main函数里面的事情:
1、/* 初始化lua */
lua_State* l = lua_open();
2、/* 载入Lua基本库 */
luaL_openlibs(L);
另:
lua_State * l = luaL_newstate() ; //创建lua运行环境
if ( l == NULL )
{
err_return(-1,"luaL_newstat() failed",1);
}
1、2 和 创建lua运行环境的不同;

3、/* 载入脚本 */
luaL_dofile(L, "add.lua");
luaL_dofile 相当于:(luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
当然使用luaL_loadfile 要注意调用 lua_pcall 函数 清空堆栈;

4、/* 调用Lua函数 */

这里就可以调用之前定义好的功能函数;具体功能封装到C的函数中;

5、/* 显示结果 */
printf( "The sum is %d/n", sum );

6、/* 清除Lua */
lua_close(L);

补充上面第四步,分析封装到C函数中的lua函数调用方法:
int luaadd ( int x, int y )
{
int sum; //定义一个变量作为返回值;
/* 通过名字得到Lua函数 */
lua_getglobal(L, "add"); //使用lua_getglobal得到全局变量;
/* 第一个参数 */
lua_pushnumber(L, x); //将第一个参数压入栈中;

/* 第二个参数 */
lua_pushnumber(L, y); //第二个参数压入栈中;

/* 调用函数,告知有两个参数,一个返回值 */
lua_pcall(L, 2, 1,0); //调用此函数会自动将参数弹出栈,只保留返回值;

/* 得到结果 */
sum = (int)lua_tointeger(L, -1);
lua_pop(L, 1); //将返回值从栈中清除;

return sum;
}
(4)C调用lua全局变量
main函数里面的初始化一样;
另外调用全局变量用的也是lua_getglobal()方法;
比如:lua_getglobal(l,"width"); //获取lua中定义的变量

各种交互具体代码示例:

extern "C"
{
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}

#define err_exit(num,fmt,args) /
do{printf("[%s:%d]"fmt"/n",__FILE__,__LINE__,##args);exit(num);} while(0)
#define err_return(num,fmt,args) /
do{printf("[%s:%d]"fmt"/n",__FILE__,__LINE__,##args);return(num);} while(0)

//lua中调用的c函数定义,实现加法
int csum(lua_State* l)
{
int a = lua_tointeger(l,1) ;
int b = lua_tointeger(l,2) ;
lua_pushinteger(l,a+b) ;
return 1 ;
}

int main(int argc,char** argv)
{
lua_State * l = luaL_newstate() ; //创建lua运行环境
if ( l == NULL )
{
err_return(-1,"luaL_newstat() failed",1);
}
//int ret = 0 ;
int ret = luaL_loadfile(l,"func.lua") ; //加载lua脚本文件
if ( ret != 0 )
err_return(-1,"luaL_loadfile failed",1) ;
ret = lua_pcall(l,0,0,0) ;
if ( ret != 0 )
err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1)) ;

lua_getglobal(l,"width"); //获取lua中定义的变量
lua_getglobal(l,"height"); //如果改变了字符串的值,则不会打印出正确的结果,默认值是0
printf("height:%ld width:%ld/n",lua_tointeger(l,-1),lua_tointeger(l,-2)) ;
int n = lua_gettop(l); //要声明变量等于lua_gettop()
lua_pop(l,1) ; //恢复lua的栈

int a = 11 ;
int b = 12 ;
lua_getglobal(l,"sum"); //调用lua中的函数sum
lua_pushinteger(l,a) ;
lua_pushinteger(l,b) ;
int m = lua_gettop(l);
ret = lua_pcall(l,2,1,0) ;
//if ( ret != 0 ) err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1)) ;
printf("sum:%d + %d = %ld/n",a,b,lua_tointeger(l,-1)) ;
lua_pop(l,1) ;

const char str1[] = "hello" ;
const char str2[] = "world" ;
lua_getglobal(l,"mystrcat"); //调用lua中的函数mystrcat
lua_pushstring(l,str1) ;
lua_pushstring(l,str2) ;
ret = lua_pcall(l,2,1,0) ;
// if ( ret != 0 ) err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1)) ;
printf("mystrcat:%s%s = %s/n",str1,str2,lua_tostring(l,-1)) ;
lua_pop(l,1) ;

//lua_pushcfunction(l,csum) ; //注册在lua中使用的c函数
//lua_setglobal(l,"csum") ; //绑定到lua中的名字csum
lua_register(l,"csum",csum);

lua_getglobal(l,"mysum"); //调用lua中的mysum函数,该函数调用本程序中定义的csum函数实现加法
lua_pushinteger(l,a) ;
lua_pushinteger(l,b) ;
ret = lua_pcall(l,2,1,0) ;
//if ( ret != 0 ) err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1)) ;
printf("mysum:%d + %d = %ld/n",a,b,lua_tointeger(l,-1)) ;
lua_pop(l,1) ;

lua_close(l) ; //释放lua运行环境
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: