Lua提供的很多特性(垃圾收集,高效的字符串处理,便捷的开发)都是很吸引人的,能够把C中复杂的业务逻辑剥离到LUA脚本中处理的话会方便不少。下面做的几组测试示例分别展示了C语言如何调用Lua脚本,调用Lua函数以及Lua脚本如何调用C中自定义函数。
测试一:最经典的Hello World
main.cpp
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "luaconf.h"
#include "lauxlib.h"
}
int main(void)
{
//create a new lua state
lua_State *L = luaL_newstate();
//open all standard lua libraries into given state
luaL_openlibs(L);
//load and run the given file
luaL_dofile(L, "test.lua");
//destroy all objects in the given lua state
lua_close(L);
return 0;
}
test.lua
print("Hello world")
测试二:从Lua脚本获取width和height的值
main.cpp
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "luaconf.h"
#include "lauxlib.h"
}
int main(void)
{
int width,height;
lua_State *L = luaL_newstate();
//to have access to certain libraries
luaopen_base(L);
luaopen_io(L);
luaopen_string(L);
//load the given file and run it as a function
if (luaL_loadfile(L, "test.lua") || lua_pcall(L, 0, 0, 0))
{
luaL_error(L, "cannot run configuration file: %s",lua_tostring(L, -1));
}
//pushes onto the stack the value of the global variables
lua_getglobal(L, "width");
lua_getglobal(L, "height");
if(!lua_isnumber(L, -2))
luaL_error(L, "'width' should be a number\n");
if(!lua_isnumber(L, -1))
luaL_error(L, "'height' should be a number\n");
width = (int)lua_tonumber(L, -2);
height = (int)lua_tonumber(L, -1);
printf("width is %d , height is %d\n", width, height);
lua_close(L);
return 0;
}
test.lua
width = 200
height = 300
测试三:调用Lua函数实现两个数相加
main.cpp
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "luaconf.h"
#include "lauxlib.h"
}
int main(void)
{
int x = 3, y = 4, z;
lua_State *L = luaL_newstate();
luaopen_base(L);
luaopen_io(L);
luaopen_string(L);
if (luaL_loadfile(L, "test.lua") || lua_pcall(L, 0, 0, 0))
{
luaL_error(L, "cannot load lua file: %s",lua_tostring(L, -1));
}
//push function and arguments
lua_getglobal(L, "add");
lua_pushnumber(L, x);
lua_pushnumber(L, y);
//call function
if (lua_pcall(L, 2, 1, 0) != 0)
luaL_error(L, "error running function add\n");
//get result
if(!lua_isnumber(L, -1))
luaL_error(L, "function should return a number\n");
z = lua_tonumber(L, -1);
printf("x + y = %d\n", z);
lua_close(L);
return 0;
}
test.lua
function add(x, y)
return x + y
end
测试四:调用Lua函数实现字符串截取前六位
main.cpp
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "luaconf.h"
#include "lauxlib.h"
}
int main(void)
{
char *str = "Hello World";
char *substr;
lua_State *L = luaL_newstate();
luaL_openlibs(L);
if (luaL_loadfile(L, "test.lua") || lua_pcall(L, 0, 0, 0))
{
luaL_error(L, "cannot load lua file: %s",lua_tostring(L, -1));
}
//push function and arguments
lua_getglobal(L, "substr5");
lua_pushstring(L, str);
//call function
if (lua_pcall(L, 1, 1, 0) != 0)
luaL_error(L, "error running function substr5. %s\n", lua_tostring(L, -1));
substr = (char *)lua_tostring(L, -1);
printf("substring of '%s' is %s\n", str, substr);
lua_close(L);
return 0;
}
test.lua
function substr5(str)
return string.sub(str,0,5)
end
测试五:Lua中调用自定义C函数实现计算sin值
main.cpp
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "luaconf.h"
#include "lauxlib.h"
}
#include<math.h>
static int l_sin (lua_State *L){
//get arguments
double d = lua_tonumber(L, 1);
//push results
lua_pushnumber(L, sin(d));
//number of results
return 1;
}
int main(void)
{
char *str = "Hello World";
char *substr;
lua_State *L = luaL_newstate();
luaL_openlibs(L);
//push function and set it to global varaible
lua_pushcfunction(L, l_sin);
lua_setglobal(L, "mysin");
if (luaL_loadfile(L, "test.lua") || lua_pcall(L, 0, 0, 0))
{
luaL_error(L, "cannot load lua file: %s",lua_tostring(L, -1));
}
lua_close(L);
return 0;
}
test.lua
print(mysin(1))
Lua和C两者互相的调用是通过相同类型的栈来传递函数名,参数,返回值的,简单易用。
项目的环境和示例程序可在http://dl.dbank.com/c0djezo1b6这里下载得到