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

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 !

时间: 2024-12-26 13:02:37

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

C调用lua的table里面的函数

网上搜索C.C++调用lua函数,有一大堆复制粘贴的. 但是搜索<C调用lua的table里面的函数> 怎么就没几个呢? 经过探索,发现其实逻辑是这样的: 1.根据name获取table :并判断是否为table 2.根据 name2 获取table的成员变量或方法,并判断栈顶的是否为函数 3.将函数的参数压栈,然,没有可以传入一个nil: 4.调用lua_pcall 跟调用普通lua函数的方法就一样了. 代码如下: bool call_table_func(const char * tabl

用cocos2d-android开发android游戏时调用box2d中的native本地函数问题

用cocos2d-android开发android游戏时调用box2d中的new World(Vector2,boolean)时,出现如下报错: "java.lang.UnsatisfiedLinkError: Native method not found: com.badlogic.gdx.physics.box2d.World.newWorld:(FFZ)J" 解决方法: 在当前类中添加代码: static { System.loadLibrary("gdx"

C++调用lua中的函数

测试lua脚本 一.lua中的全局函数 lua中的全局函数保存在lua的global表里 二.lua模块中的函数 lua中的模块被放在lua的global表里,模块中的函数以变量的形式保存在模块表里,比如test模块里的PrintMessage函数保存在test表里,key为PrintMessage,value是函数体.所以调用模块里的函数,首先lua_getglobal把模块压入栈,接着lua_gettable或lua_getfield把函数压入栈,最后lua_pcall调用函数.

java中调用数据库中的存储过程和函数

public static void main(String[] args) {         Connection conn =getConnection(url,user, pwd);         System.out.println("数据连接成功");         CallableStatement cs=null;         try         {    //调用数据库中的存储过程              cs = conn.prepareCall(&q

SQL中存储过程和自定义函数的区别(转载)

存储过程:     存储过程可以使得对数据库的管理.以及显示关于数据库及其用户信息的工作容易得多.存储过程是 SQL 语句和可选控制流语句的预编译集合,以一个名称存储并作为一个单元处理.存储过程存储在数据库内,可由应用程序通过一个调用执行,而且允许用户声明变量.有条件执行以及其它强大的编程功能.存储过程可包含程序流.逻辑以及对数据库的查询.它们可以接受参数.输出参数.返回单个或多个结果集以及返回值. 可以出于任何使用 SQL 语句的目的来使用存储过程,它具有以下优点: 1.可以在单个存储过程中执

SQL中存储过程和自定义函数的区别

存储过程:     存储过程可以使得对数据库的管理.以及显示关于数据库及其用户信息的工作容易得多.存储过程是 SQL 语句和可选控制流语句的预编译集合,以一个名称存储并作为一个单元处理.存储过程存储在数据库内,可由应用程序通过一个调用执行,而且允许用户声明变量.有条件执行以及其它强大的编程功能.存储过程可包含程序流.逻辑以及对数据库的查询.它们可以接受参数.输出参数.返回单个或多个结果集以及返回值. 可以出于任何使用 SQL 语句的目的来使用存储过程,它具有以下优点: 1.可以在单个存储过程中执

SQL中存储过程与自定义函数的区别

存储过程 存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它.存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程. 优点 ①重复使用.存储过程可以重复使用,从而可以减少数据库开发人员的工作量. ②提高性能.存储过程在创建的时候在进行了编译,将来使用的时候不再重新翻译.一般的SQL语句每

C++调用C中编译过的函数要加extern &quot;C&quot;

C++语言支持函数重载,C语言不支持函数重载.函数被C++编译后在库中的名字与C语言的不同.假设某个C 函数的声明如下:void foo(int x, int y);该函数被C 编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字用来支持函数重载和类型安全连接.由于编译后的名字不同,C++程序不能直接调用C 函数.C++提供了一个C 连接交换指定符号extern“C”来解决这个问题.例如:extern “C”{void foo(int x, int y)

lua中的closure(闭合函数)

若将一个函数写在另一个函数之内,那么这个位于内部的函数便可以访问外部函数的局部变量. function newCounter() local i = 0 return function()----匿名函数 i = i + 1 return i end end c1 = newCounter() c2 = nweCounter() print(c1())---->1 print(c1())---->2 print(c2())---->1 print(c1())---->3 print