标签:col 目的 error new 创建 完成 解释 信息 主程
1、首先说下目的,为什么要这么做 ?
正式项目中,希望主程序尽量不做修改,于是使用C/C++完成功能的主干(即不需要经常变动的部分)用lua这类轻量级的解释性语言实现一些存在不确定性的功能逻辑;所以,程序功能如有问题,只需对lua脚本作出修改,而修改脚本的好处是简单高效,改完脚本后重新执行程序便能看到效果。
2、具体怎么做?
一般来说,C/C++调用lua接口或是数据交互,首先要做的是包含lua相关操作的头文件以及lua库相关的头文件,然后调用接口创建lua环境、用操作栈的规则和lua交互数据或参数(调用lua函数);执行所需操作或是取得所需数据后销毁lua环境。以下用源码进行详细解释:
①、C++源文件
1 //1、包含头文件 2 extern "C" 3 { 4 #include<lua5.2/lua.h> 5 #include<lua5.2/lauxlib.h> 6 #include<lua5.2/lualib.h> 7 } 8 //2、创建lua环境 9 lua_State *L = luaL_newstate(); 10 if(L == NULL) 11 { 12 cout<<"Creat Lua State Error !"<<endl; 13 return 1; 14 } 15 //如需在终端输出打印信息,库是必须加载的,否则看不到lua的print信息 16 luaL_openlibs(L); 17 //3、加载lua脚本 18 const string lua_path = "../scripts/"; 19 const string file = "Function.lua"; 20 string script = lua_path + file ; 21 int ret = luaL_dofile(L ,script.c_str()); 22 if(ret) 23 { 24 cout<<"Lua doFile Error !"<<endl; 25 return 1; 26 } 27 //4、调用脚本中已写好的函数 28 //a、无参函数 29 lua_getglobal(L, "ruler"); //函数名为ruler 30 lua_pcall(L,0,0,0); //用保护模式调用lua函数,入参个数为0、出参个数为0、无自定义错误处理 31 32 //b、有参函数 33 lua_getglobal(L, "add"); //函数名为add 34 lua_pushnumber(L, number1); //第一个入参 35 lua_pushnumber(L, number2); //第二个入参 36 lua_pcall(L,2,1,0); //函数有两个入参,一个出参,所以函数形式为add(a,b) 37 //5、获得返回值,单回值情况下调用完成后lua会把结果放到栈顶,多返回值时,按照规则存放,具体查API 38 if(lua_isnumber(L,-1)) 39 { 40 cout<<"the result is :"<<lua_tonumber(L,-1)<<endl; 41 } 42 //6、销毁lua环境 43 lua_close(L);
②、lua脚本
1 //7、add,lua脚本内容 2 function add(a,b) 3 return a+b; 4 end 5 6 function ruler() 7 print("this is some thing need to tell you !!!"); 8 end
3、结语:
总之,lua和C/C++交互必须依靠媒介——栈;用lua作为配置文件时,内容为静态的,组织为table,C++通过table相关接口操作数据;当用lua作为较为复杂的函数语言时,当前lua中所有全局函数都可以被宿主语言调用,且如果要用lua输出打印信息以便调试,此时必须open lua库,否则将看不到print相关内容,且全局的print都会导致difile()失败。
典型操作就这两类,其余的,都可以通过查阅API手册尝试去使用,have fun !
标签:col 目的 error new 创建 完成 解释 信息 主程
原文地址:http://www.cnblogs.com/zhangyi-studio/p/7482211.html