1、lua作为一个小巧的脚本语言,很适合做二次开发接口。比如我们开发一个业务框架,其他人写lua脚本来实现具体的功能。
2、c调用lua脚本
2.1 下载lua源代码 wget http://www.lua.org/ftp/lua-5.3.4.tar.gz
2.2 解压 tar -xzvf lua-5.3.4.tar.gz
2.3 编译 make linux (如果报错,可能需要安装yum install -y readline-devel)
编译后,在src目录下,生产来lua,luac,lualib.a等文件
2.4 创建一个c的代码目录ctest,并将lua src下的几个文件拷贝到ctest下的include和lib目录
271 mkdir ctest
272 cd ctest
273 mkdir lib
274 mkdir include
275 ls ../../lua-5.3.4/src/luaxlib.h
276 cp ../../lua-5.3.4/src/lua.h include/
277 cp ../../lua-5.3.4/src/lualib.h include/
278 cp ../../lua-5.3.4/src/lauxlib.h include/
279 cp ../../lua-5.3.4/src/luaconf.h include/
280 cp ../../lua-5.3.4/src/liblua.a lib
2.5 编写一个add.lua代码
function add(x,y)
return x + y
end
2.6 编写main.c代码
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
/*
编译和链接
gcc -I include -c main.c
gcc -lm -ldl -o main main.o lib/liblua.a
-lm是什么?
使用math.h中声明的库函数还有一点特殊之处,gcc命令行必须加-lm选项,因为数学函数位于libm.so库文件中(这些库文件通常位于/lib目录下),-lm选项告诉编译器,我们程序中用到的数学函数要到这个库文件里找。本书用到的大部分库函数(例如printf)位于libc.so库文件中,使用libc.so中的库函数在编译时不需要加-lc选项,当然加了也不算错,因为这个选项是gcc的默认选项。
-ldl是什么?
Linux有时我们需要在运行时指定库的路径去加载库,而不是依赖于系统自动动态链接。比如说我们在需要做到动态加载库插件时就会用到动态装载库的特性(比如像lighthttpd和nginx的动态mod功能),Linux提供了函数来帮助我们做到这件事,主要的几个函数为:dlopen,dlsym,dlclose
*/
int main(void){
lua_State *L = luaL_newstate();
luaL_openlibs(L); // 加载基本库(print在其中)
luaL_dofile(L,"add.lua");
lua_getglobal(L,"add");
lua_pushnumber(L,23);
lua_pushnumber(L,48);
lua_call(L, 2, 1);
/*取出返回值*/
int sum = (int)lua_tonumber(L, -1);
/*清除返回值的栈*/
lua_pop(L,1);
printf("sum=%d\n",sum);
lua_close(L);
return 0;
}
lua_getglobal(L,"print");
lua_pushnumber(L,23);
lua_pushnumber(L,33);
lua_call(L, 2, 0);//打印两个数字
lua_pushnumber(L,4);
lua_setglobal(L,"abc");//栈顶元素赋给全局变量abc (如果没有,就新创建这个全局变量)
lua_getglobal(L,"print");//把print函数放到栈顶
lua_getglobal(L,"abc");//把全局变量abc放到栈顶
lua_call(L, 1, 0);
2.7 参考main.c中的注释,编译和链接c代码。最后执行./main 程序
3、java调用lua脚本
3.1 可以使用java版的lua。(也可以使用java本地调用c)
<dependency>
<groupId>org.luaj</groupId>
<artifactId>luaj-jse</artifactId>
<version>3.0.1</version>
</dependency>
public static void main( String[] args ){
Globals globals = JsePlatform.standardGlobals();
LuaValue chunk2 = globals.loadfile("luascript/api.lua");
chunk2.call();
LuaValue ff = globals.get(LuaValue.valueOf("count"));//找到count 函数
ff.call();
}
public static void main2( String[] args ){
System.out.println( "Hello World! " + System.getProperty("user.dir"));
Globals globals = JsePlatform.standardGlobals();
LuaValue chunk2 = globals.loadfile("luascript/main2.lua");
chunk2.call();
LuaValue ff = globals.get(LuaValue.valueOf("ff"));//找到ff函数
ff.call( LuaValue.valueOf("pp") );
LuaValue[] temp = new LuaValue[8];
for (int i = 0; i < 8; i++) {
temp[i]=LuaValue.valueOf(i);
}
LuaValue table = LuaValue.tableOf(temp);
LuaValue tableTest = globals.get(LuaValue.valueOf("tableTest"));//找到tableTest函数
tableTest.call( table );
}
注意:lua脚本调用另外一个lua脚本,需要使用包
# mo.lua 是一个包
mo={}
print("6666")
function mo.test()
print("8888")
end
return mo
#调用方
#注意下面这两行,lua默认在当前目录下找其他包,如果按照1 重新添加了luascript目录,则 require时,可以直接写require "mo"
# 1 package.path=package.path..";luascript/?.lua"
require "luascript.mo"
print("ddd")
print(package.path)
function ff(name)
print(name)
end
function tableTest(table)
print(#table)
for i,v in pairs(table) do
print(i ..'===>'..v)
end
end
mo.test()