lua 基础教程
最近在看lua,觉得很有趣,发现没有最新版本的例子,所以自己就别人的博客里弄了源码,然后改成最新版本的luaCAPI.
关于lua非常基础的就不介绍了,咱们就从简单的测试开始吧。
在此之前如果没有搭好lua在win32下的环境,请看https://www.nhooo.com/article/61451.htm
1.C/C++执行lua脚本
我只是用改用了最新的lua的CAPI。不多说,直接上代码
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
extern"C"
{
#include"lua.h"
#include"lualib.h"
#include"lauxlib.h"
};
usingnamespacestd;
intmain()
{
lua_State*pLuaState=luaL_newstate();
/*载入lua基本库*/
luaL_openlibs(pLuaState);
//luaopen_base(pLuaState);
//luaopen_io(pLuaState);//替换老版本的lua_iolibopen(pLuaState);
//luaopen_string(pLuaState);//替换老版本的lua_strlibopen(pLuaState);
//luaopen_math(pLuaState);//替换老版本的lua_mathlibopen(pLuaState);
//luaopen_debug(pLuaState);//替换老版本的lua_dblibopen(pLuaState);
/*运行脚本*/
luaL_dofile(pLuaState,"./script/hw.lua");
/*清除lua*/
lua_close(pLuaState);
/*暂停*/
cout<<"Pressentertoexit…"<<endl;
getchar();
return0;
}
hw.lua的源码:
print("HelloWord!");
这个例子只是简单的执行了一个lua脚本。
其中:lua_newstate是核心函数,要求提供内存分配函数,luaL_newstate是辅助库函数,采用默认的内存分配函数。lua_open是5.0时代的产物,5.1是luaL_newstate的宏,5.2里面已经没有了。
2.C/C++调用lua函数
话不多说,直接上代码
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
extern"C"
{
#include"lua.h"
#include"lualib.h"
#include"lauxlib.h"
};
usingnamespacestd;
/************************************************************************/
//函数功能:调用lua函数
//函数参数:
//Llua虚拟机
//x
//y
//函数返回:
//sum
//核心函数lua_call()
/*
调用一个函数。
要调用一个函数请遵循以下协议:首先,要调用的函数应该被压入堆栈;接着,把需要传递给这个函数的参数按正序压栈;
这是指第一个参数首先压栈。最后调用一下lua_call;nargs是你压入堆栈的参数个数。当函数调用完毕后,所有的参数以及函数本身都会出栈。
而函数的返回值这时则被压入堆栈。返回值的个数将被调整为nresults个,除非nresults被设置成LUA_MULTRET。
在这种情况下,所有的返回值都被压入堆栈中。Lua会保证返回值都放入栈空间中。
函数返回值将按正序压栈(第一个返回值首先压栈),因此在调用结束后,最后一个返回值将被放在栈顶。
被调用函数内发生的错误将(通过longjmp)一直上抛。
*/
/************************************************************************/
intluaadd(lua_State*L,intx,inty)
{
intsum;
/*通过名字获取Lua函数*/
lua_getglobal(L,"add");
/*向栈中压入第一个参数*/
lua_pushnumber(L,x);
/*向栈中压入第二个参数*/
lua_pushnumber(L,y);
/*调用函数*/
lua_call(L,2,1);
/*得到结果
把给定索引处的Lua值转换为lua_Integer这样一个有符号整数类型。
这个Lua值必须是一个数字或是一个可以转换为数字的字符串,否则,lua_tointeger返回0。*/
sum=(int)lua_tointeger(L,-1);
/*从堆栈中弹出n个元素*/
//n
lua_pop(L,1);
returnsum;
}
intmain()
{
intsum;
/*初始化lua虚拟机*/
lua_State*L=luaL_newstate();
/*载入lua基本库*/
luaL_openlibs(L);
/*载入脚本*/
luaL_dofile(L,"./script/test.lua");
/*调用lua函数*/
sum=luaadd(L,10,15);
/*显示结果*/
cout<<"Thesum="<<sum<<endl;
/*清除lua虚拟机*/
lua_close(L);
/*显示结果并暂停*/
cout<<"Pressentertoexit…"<<endl;
getchar();
return0;
}
test.lua代码为:
functionadd(x,y) returnx+y; end
其中关于lua的堆栈问题,目前我还没有了解,希望大家多多指教。
3.lua调用C/C++函数
代码为:
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
extern"C"
{
#include"lua.h"
#include"lualib.h"
#include"lauxlib.h"
};
usingnamespacestd;
staticintaverage(lua_State*L)
{
/*得到参数个数*/
intn=lua_gettop(L);
/*定义和*/
doublesum=0;
/*循环变量*/
inti;
/*循环取值求和*/
for(i=1;i<=n;i++)
{
sum+=lua_tonumber(L,i);
//cout<<sum<<endl;
}
//cout<<"fffffff"<<endl;
/*压入平均值*/
lua_pushnumber(L,sum/n);
/*压入和*/
lua_pushnumber(L,sum);
/*返回返回值个数*/
return2;
}
intmain()
{
/*初始化Lua虚拟机*/
lua_State*L=luaL_newstate();
/*打开lua基本库*/
luaL_openlibs(L);
/*注册函数*/
lua_register(L,"average",average);
/*运行脚本*/
luaL_dofile(L,"./script/avg.lua");
/*清除lua虚拟机*/
lua_close(L);
/*打印暂停*/
cout<<"Pressentertoexit…"<<endl;
getchar();
return0;
}
avg.lua源码为:
functionmain()
localavg,sum=average(2,2,2,2,2);
print("Theavgis",avg);
print("Thesumis",sum);
end
main();