c++与lua交互

1、c++中执行和加载lua脚本

c++中直接执行lua文件,加载lua代码到虚拟机
main.cpp

#include <stdio.h>

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
/* LUA接口声明*/
lua_State* L;
int main ( int argc, char *argv[] )
{
	/* 初始化 Lua */
	L = lua_open();
	/*载入LUA库 */
	lua_baselibopen(L);
	/* 运行LUA脚本 */
	lua_dofile(L, "test.lua");
	/* 清除 Lua */
	lua_close(L);
	return 0;
}

测试脚本test1.lua:

-- simple test
print "Hello, World!"


2、c++与lua相互函数调用 

(1)c调用lua函数

 lua_call  和 lua_pcall 是提供在c/c++调用lua函数的方法,要求 栈上的顺序是 functor + 参数1 + 参数2 +... 的排列顺序。
函数声明:
LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc)
第一个参数虚拟机指针,第二个参数指定有多少个参数,第三个指定有几个返回值,第四个当发生错误的时候用函数(所在的交互栈的位置,如果是1,表示错误处理函数在栈的1号位置上,就是传入的那个错误处理函数)。
如果指定有n个参数,则要先把函数入栈,然后再把n个参数压入栈,调用lua_pcall,注意,lua_pcall如果要调用函数,函数必须在栈底。
如果有指定返回值,在压入结果前,lua_pcall会删除栈中函数及其参数。故lua_pcall后调用lua_pop恢复栈时,只需弹出函数返回值结果数即可。
lua的虚拟栈是有限的,如果不够用会先破坏先前的数据。

LUA_API int (lua_call) (lua_State *L, int nargs, int nresults)
类似lua_pcall,只是没有错误处理函数

(1-1)调用lua_call

测试脚本test2.lua:

----fun.lua--------
function add ( x, y )
return x + y
end

调用lua_dofile()将执行脚本,则该脚本代码会被加载到虚拟机中。
 

LUA的函数可以接收多个参数,并可以返回多种类型的结果,这里使用了堆栈。

先把函数和参数压栈调用函数lua_call(),调用这个函数之后,返回的结果将存在于堆栈中。

步骤:
1.用lua_getglobal()把add函数放入堆栈
2.用lua_pushnumber()把第一个参数压入堆栈
3.用lua_pushnumber()把第二个参数压入堆栈
4.用lua_call()调用函数。
5,现在用lua_tonumber从堆栈头取出结果
6,最后用lua_pop从堆栈中移除结果值。


代码:luaadd.cpp

#include <stdio.h>
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
//lua虚拟机对象
lua_State* L;
int luaadd ( int x, int y )
{
	int sum;
	//压入函数名到栈顶(lua函数)
	lua_getglobal(L, "add");
	//压入第一个参数
	lua_pushnumber(L, x);
	//压入第二个参数
	lua_pushnumber(L, y);
	//执行栈底函数,传入两个参数,返回一个结果
	lua_call(L, 2, 1);//或者lua_pcall(L,2,1,0);
	//获取栈顶结果
	sum = (int)lua_tonumber(L, -1);
	lua_pop(L, 1);//清除结果
	return sum;
}

int main ( int argc, char *argv[] )
{
	int sum;
	//初始化虚拟机对象
	L = lua_open();
	//加载lua类库
	lua_baselibopen(L);
	//加载lua脚本
	lua_dofile(L, "add.lua");
	//执行lua中的add函数,返回结果
	sum = luaadd( 10, 15 );
	//打印结果
	printf( "The sum is %d\n", sum );
	//清除lua虚拟机
	lua_close(L);
	return 0;
}

(1-2)调用lua_pcall

使用lua_pcall 调用lua函数,并在出错时处理错误。

错误处理函数在lua虚拟机中,名为__G__TRACKBACK__

lua_getglobal(L, "__G__TRACKBACK__");//通过函数名,压入错误处理函数  

if (lua_type(L, -1) != LUA_TFUNCTION)   //尼马,居然找不到,那肯定是拼写错误!  
{  
	printf("[LUA ERROR] can't find function <__G__TRACKBACK__>err");  
	lua_settop(L, top);  
	return;  
}  

int errfunc = lua_gettop(m_state);                   //刚压入的函数,肯定是栈顶哦,那gettop就是他的索引  

lua_getglobal(L, "main");                     //查找要执行的函数  
if (lua_type(L, -1) != LUA_TFUNCTION)  
{  
	printf("[LUA ERROR] can't find function <main>err:%s", lua_tostring(m_state, -1));  
	lua_settop(m_state, top);  
	return;  
}  
if (lua_pcall(L, 0, 0, errfunc) != 0)  //执行函数main,参数0,返回值0,errfunc是错误处理函数  
{  
	lua_settop(L, top);  
	return;  
}  
lua_settop(L, top);  


1)错误处理函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值