C语言调用Lua函数
在lua.c中的main函数中,删除已有代码,改为如下代码:
void test2(lua_State* L)
{
//获取堆栈中已经存在多少个元素
int top = lua_gettop(L);
printf("top:[%d]\n", top);
//把全局变量名为func2的函数压栈,返回该值的类型
int type = lua_getglobal(L, "func2");
//printf("type:%d\n", type);
//以保护模式调用函数,调用后必须还原Lua堆栈,比如调用函数后返回两个值,必须使用lua_pop(L,2)将Lua堆栈清空。
//当函数被调用完毕后,所有的参数以及函数本身都会出栈,而函数的返回值这时则被压入栈。
//int lua_pcall(lua_State* L,int nergs,int nresults,int msgh);
//L:Lua虚拟机
//nergs:压入栈的形参个数
//nresults:返回的参数个数
//msgh如果为0,返回栈顶的错误消息就和原始消息完全一致。
//压入一个字符串
lua_pushstring(L, "Hello Wolrd");
//压入一个整数
lua_pushnumber(L, 1000);
//压入一个布尔类型
lua_pushboolean(L, 666);
//调用函数
if (0 != lua_pcall(L, 3, 2, 0))
printf("error[%s]\n", lua_tostring(L, -1));
printf("%d=====\n", lua_gettop(L));
const char* str = lua_tostring(L, -2);//获取返回的值
int value = lua_tonumber(L, -1);//-1表示栈顶(-2栈顶下面一个),1表示栈底
printf("栈顶:%d 栈顶之下:%s\n", value, str);
//清除返回值,即进行堆栈平衡
lua_pop(L, lua_gettop(L) - top);//或者,由于已经知道调用该函数返回两个参数,可以直接使用lua_pop(L, 2);
top = lua_gettop(L);
printf("top:[%d]\n", top);
printf("----分界线---\n");
}
int main(int argc, char** argv) {
// 创建一个虚拟机
lua_State* L = luaL_newstate();
// 加载一些常用的系统库
luaL_openlibs(L);
if (luaL_dofile(L, "main.lua"))
printf("%s\n", lua_tostring(L, -1));
test2(L);
test2(L);
test2(L);
test2(L);
// 关闭虚拟机
lua_close(L);
return 0;
}
注意需要跟lua.c文件放在同一个文件路径下):
-- main.lua
function func2(a,b,c)
print(a,b,c)
return "hello world",123
end
运行结果如下:
C语言设置一个table数据给Lua
示例1
在lua.c中的main函数中,删除已有代码,改为如下代码:
int main(int argc, char** argv) {
// 创建一个虚拟机
lua_State* L = luaL_newstate();
// 加载一些常用的系统库
luaL_openlibs(L);
lua_newtable(L);//创建一个table类型
lua_pushstring(L, "dlw");//此刻堆栈中有两个元素,table和“dlw”
int top = lua_gettop(L);
printf("top:%d\n", top);
lua_pushstring(L, "111");//此刻堆栈中有三个元素,“111”位于栈顶,“dlw”位于栈顶下方
top = lua_gettop(L);
printf("top:%d\n", top);
lua_settable(L, -3);//将堆栈中的key和value设置到table中去,为{"dlw" = "111"},此刻栈中只剩下table
top = lua_gettop(L);
printf("top:%d\n", top);
lua_setglobal(L, "tab"); //将当前创建的table命名为 tab全局变量,此刻堆栈中为空
top = lua_gettop(L);
printf("top:%d\n", top);
lua_newtable(L);
lua_pushstring(L, "dlw");//此刻堆栈中有两个元素
top = lua_gettop(L);
printf("top:%d\n", top);
lua_setfield(L, 1, "name");//或者lua_setfield(L, -2, "name");此刻堆栈中有一个元素,表示在栈顶之下插入“name”,此时{"name"="dlw"},再将其压入table中
top = lua_gettop(L);
printf("top:%d\n", top);
lua_setglobal(L, "tab1");
// 加载lua文件并执行 名称为 main.lua
if (luaL_dofile(L, "main.lua"))
{
// 在lua中 -1表示栈顶 如果出错 出错结果会放置在栈顶中
printf("%s\n", lua_tostring(L, -1));
}
// 关闭虚拟机
lua_close(L);
return 0;
}
注意需要跟lua.c文件放在同一个文件路径下):
-- main.lua
print(tab.dlw)
print(tab1.name)
运行结果如下:
示例2
int main(int argc, char** argv) {
// 创建一个虚拟机
lua_State* L = luaL_newstate();
// 加载一些常用的系统库
luaL_openlibs(L);
//创建一个table
lua_newtable(L);
lua_pushstring(L, "dlw");
//做一个等价于 table["name"] = "dlw"的操作,这里"name"是给出的索引处的值,而"dlw"则是栈顶的值
lua_setfield(L, 1, "name");
lua_pushstring(L, "Hello World");
lua_rawseti(L, -2, 1);//将指定索引位置的元素与栈顶元素进行关联,即table[1] = "Hello World";
lua_setglobal(L, "tab");//将当前创建的table命名为tab全局变量
// 加载lua文件并执行 名称为 main.lua
if (luaL_dofile(L, "main.lua"))
{
// 在lua中 -1表示栈顶 如果出错 出错结果会放置在栈顶中
printf("%s\n", lua_tostring(L, -1));
}
// 关闭虚拟机
lua_close(L);
return 0;
}
-- main.lua
print(tab.name)
print(tab[1])
运行结果如下:
C语言调用Lua设置的table类型
在lua.c中的main函数中,删除已有代码,改为如下代码:
int main(int argc, char** argv) {
// 创建一个虚拟机
lua_State* L = luaL_newstate();
// 加载一些常用的系统库
luaL_openlibs(L);
// 加载lua文件并执行 名称为 main.lua
if (luaL_dofile(L, "main.lua"))
{
// 在lua中 -1表示栈顶 如果出错 出错结果会放置在栈顶中
printf("%s\n", lua_tostring(L, -1));
}
int top = lua_gettop(L);
printf("%d\n", top);
lua_getglobal(L, "tab");//获取全局变量tab
top = lua_gettop(L);
printf("%d\n", top);
//数据类型检查,检查是否为表。
luaL_checktype(L, -1, LUA_TTABLE);//此刻堆栈中仍然是一个元素
top = lua_gettop(L);
//printf("%d\n", top);
//将key压入栈中,函数将返回value值至栈顶
if (LUA_TSTRING == lua_getfield(L, -1, "name"))//判断是否为字符串
{
top = lua_gettop(L);
printf("%d\n", top);
const char* str = luaL_checkstring(L, -1);
printf("%s\n", str);
}
lua_pop(L, 1);//平衡堆栈
//将key压入栈中,函数将返回value值至栈顶
if (LUA_TSTRING == lua_geti(L, -1, 2))
{
const char* str = luaL_checkstring(L, -1);
printf("%s\n", str);
}
lua_pop(L, 1);// 平衡堆栈
lua_pop(L, 1);// 平衡堆栈,这个是对lua_getglobal(L, "tab")的平衡
// 关闭虚拟机
lua_close(L);
return 0;
}
注意需要跟lua.c文件放在同一个文件路径下):
-- main.lua
tab = {name = 'dlw'}
tab[1] = 123321
tab[2] = '123321aa'
运行结果如下: