加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

lua和C交互框架

发布时间:2020-12-14 22:16:55 所属栏目:大数据 来源:网络整理
导读: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

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__,##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,1);
??????? }
1、2 和 创建lua运行环境的不同;

3、/* 载入脚本 */
luaL_dofile(L,"add.lua");
luaL_dofile 相当于:(luaL_loadfile(L,filename) || lua_pcall(L,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,args)? /
??? do{printf("[%s:%d]"fmt"/n",##args);exit(num);} while(0)
#define err_return(num,##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,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) ;
??? 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),-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,1,0) ;
??? //if ( ret != 0 ) err_return(-1,-1)) ;
??? printf("sum:%d + %d = %ld/n",a,b,-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,0) ;
?? // if ( ret != 0 ) err_return(-1,-1)) ;
??? printf("mystrcat:%s%s = %s/n",str1,str2,51); font-family:Arial; font-size:14px; line-height:26px"> ??? //lua_pushcfunction(l,csum) ;???????? //注册在lua中使用的c函数
??? //lua_setglobal(l,"csum") ;?????????? //绑定到lua中的名字csum
?lua_register(l,csum);

??? lua_pushinteger(l,b) ;
??? ret = lua_pcall(l,-1)) ;
??? printf("mysum:%d + %d = %ld/n",51); font-family:Arial; font-size:14px; line-height:26px"> ??? lua_close(l) ;???????????????????? //释放lua运行环境 ??? return 0 ; }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读