简述C/C++调用lua中实现的自定义函数

1、首先说下目的,为什么要这么做 ?

   在此之前,如果不知道C和lua怎么进行数据交互的童鞋,请移步另一篇文章《Linux下C/C++和lua交互-Table》。

        正式项目中,希望主程序尽量不做修改,于是使用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 !

作者:丶Ruy

出处:http://cnblogs.com/zhangyi-studio

联系:www.zhangyi.studio@gmail.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如有问题或建议,请多多赐教,非常感谢。
原文地址:https://www.cnblogs.com/zhangyi-studio/p/7482211.html