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 函数 清空堆栈;
这里就可以调用之前定义好的功能函数;具体功能封装到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中的mysum函数,该函数调用本程序中定义的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 ; }