1.lua访问c中的栈变量
void lua_setglobal (lua_State *L, const char *name);
将虚拟栈中,将栈顶元素弹出,作为全局 lua 变量 name 的值。 Pops a value from the stack
and sets it as the new value of global name。
//main.cpp
#include <stdio.h>
#include "lua.hpp"
extern "C"{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_pushinteger(L,18); //入栈
lua_setglobal(L,"age"); //出栈的同时给与18一个名字,age代表18就到全局的global里面去了
lua_pushstring(L,"nzsoft"); //入栈
lua_setglobal(L,"org");
luaL_dofile(L,"yy.lua");
lua_close(L);
return 0;
}
//yy.lua
print("age",age)
print("org",org)
测试结果:
2.lua访问c中入栈的表
void lua_setfield (lua_State *L, int index, const char *k);
上式,等价于 t[k] = v, t 是栈上索引为 index 的表, v 是栈顶的值。函数结束,栈顶值 v
会被弹出。
//main.cpp
#include <stdio.h>
#include "lua.hpp"
extern "C"{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_newtable(L); //产生一个空表,并入栈,现在table在-1的位置
lua_pushstring(L,"age"); //先压key
lua_pushinteger(L,18); //再压value
printf("Stack size = %d\n",lua_gettop(L)); //Stack size = 3
//现在栈元素为:18在-1的位置,age在-2的位置,{}在-3的位置
//lua_settable运行完后,k和v都会压入到表中,{k=v} -1,三合一
lua_settable(L,-3);
/*lua_pushstring(L,"org"); //压key
lua_pushstring(L,"nzsoft"); //压value
printf("Stack size = %d\n",lua_gettop(L)); //Stack size = 3
lua_settable(L,-3); */
lua_pushstring(L,"nzsoft");
//lua_setfield等价于 t[k] = v, t 是栈上索引为 index 的表, v 是栈顶的值。
//函数结束,栈顶值 v会被弹出。
lua_setfield(L,-2,"org");
printf("Stack size = %d\n",lua_gettop(L)); //Stack size = 1
//void lua_setglobal (lua_State *L, const char *name);
//将虚拟栈中,将栈顶元素弹出,作为全局 lua 变量 name 的值
lua_setglobal(L,"table") //现在栈中还剩下一个table,参数为-1,运行完后出栈
printf("Stack size = %d\n",lua_gettop(L)); //Stack size = 0
luaL_dofile(L,"yy.lua");
lua_close(L);
return 0;
}
//yy.lua
print("age",tab.age)
print("org",tab.org)
运行结果:
3.lua 调用 C 函数(无参无返回)
//main.cpp
#include <stdio.h>
#include "lua.hpp"
extern "C"{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
//此函数返回值类型必须是int,参数必须是lua_State *L
int func(lua_State *L)
{
printf("hello lua");
return 0;
}
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_pushcfunction(L,func);
lua_setglobal(L,"funn");
luaL_dofile(L,"yy.lua");
lua_close(L);
return 0;
}
//yy.lua
func()
测试结果:
4.lua 调用 C 函数(有参无返回)
//main.cpp
#include <stdio.h>
#include "lua.hpp"
extern "C"{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
//此函数返回值类型必须是int,参数必须是lua_State *L
int func(lua_State *L)
{
char *str = lua_tostring(L,-1);
int num2 = lua_tointeger(L,-2);
printf("%s %d\n",str,num2);
return 0;
}
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_pushcfunction(L,func);
lua_setglobal(L,"funn");
luaL_dofile(L,"yy.lua");
lua_close(L);
return 0;
}
//yy.lua
func(999,"nzsoft") //入参会被传到栈上
测试结果:
5.lua 调用 C 函数(有参有返回)
//main.cpp
#include <stdio.h>
#include "lua.hpp"
extern "C"{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
//此函数返回值类型必须是int,参数必须是lua_State *L
int func(lua_State *L)
{
int n = lua_gettop(L); //求栈上有多少个元素
int sum = 0;
for(int i =0; i < n;++i)
sum += lua_tointeger(L,i); //元素不会出栈
printf("size = %d\n",lua_gettop(L)); //size = 5
lua_pushinteger(L,sum); //栈顶元素为sum,栈顶下面全是垃圾数据
lua_pushinteger(L,sum/n);
printf("size = %d\n",lua_gettop(L)); //size = 7
return 1; //return i代表返回i个参数,在返回值后,i下面的数据全都变成垃圾
}
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_pushcfunction(L,add);
lua_setglobal(L,"add");
luaL_dofile(L,"yy.lua");
lua_close(L);
return 0;
}
//yy.lua
sum,avg= add(1,2,3,4,5)
print(sum,avg)
测试结果:
6.Lua 加载 dll 或 so(第一种方法)
加入以后C中有100个函数要供lua调用,那么可以把这些函数丢在一个表中,再把表丢到table去
//main.cpp
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
//要想注册进 lua,
//函数的定义为 typedef int (*lua_CFunction)(lua_State* L)
int printHello(lua_State * l)
{
lua_pushstring(l, "hello lua");
//返回值代表向栈内压入的元素个数
return 1;
}
int foo(lua_State * l)
{
//获得 Lua 传递过来的参数个数
int n = lua_gettop(l);
if(n != 0)
{
//获得第一个参数
int i = lua_tonumber(l, 1);
//将传递过来的参数加一以后最为返回值传递回去
lua_pushnumber(l, i+1);
return 1;
}
return 0;
}
//相加
int add(lua_State * l)
{
int n = lua_gettop(l);
int sum = 0;
for (int i=0;i<n;i++)
{
sum += lua_tonumber(l, i+1);
}
if(n!=0)
{
lua_pushnumber(l, sum);
return 1;
}
return 0;
}
//把需要用到的函数都放到注册表中,统一进行注册
static const luaL_Reg mylib[] =
{
{"printHello",printHello},
{"foo",foo),
{"add",add},
{NULL,NULL}
};
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
const luaL_Reg *libf = mylib;
////////第一种注册方法///////////////
for(;libf->func;libf++)
{
//把foo函数注册到lua,
//第二个参数代表Lua中要调用的函数名称,
//第三个参数就是c层的函数名称
lua_register(L,libf->name,libf->func);//push和lua_setglobal被封装到了lua_register
//将栈顶清空
lua_settop(L,0);
}
luaL_dofile(L,"yy.lua");
lua_close(L);
}
//yy.lua
sum = add(1,2,3,4,5)
print(sum)
print(printhello())
测试结果:
7.6.Lua 加载 dll 或 so(第二种方法:批量绑定)
//main.cpp
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
//要想注册进 lua,
//函数的定义为 typedef int (*lua_CFunction)(lua_State* L)
int printHello(lua_State * l)
{
lua_pushstring(l, "hello lua");
//返回值代表向栈内压入的元素个数
return 1;
}
int foo(lua_State * l)
{
//获得 Lua 传递过来的参数个数
int n = lua_gettop(l);
if(n != 0)
{
//获得第一个参数
int i = lua_tonumber(l, 1);
//将传递过来的参数加一以后最为返回值传递回去
lua_pushnumber(l, i+1);
return 1;
}
return 0;
}
//相加
int add(lua_State * l)
{
int n = lua_gettop(l);
int sum = 0;
for (int i=0;i<n;i++)
{
sum += lua_tonumber(l, i+1);
}
if(n!=0)
{
lua_pushnumber(l, sum);
return 1;
}
return 0;
}
//把需要用到的函数都放到注册表中,统一进行注册
static const luaL_Reg mylib[] =
{
{"printHello",printHello},
{"foo",foo),
{"add",add},
{NULL,NULL}
};
int luaopen_my(lua_State * L)
{
//凡是new都会压栈
//luaL_newlib等价于它产生了一个表,遍历了mylib里面的东西,再放入表里,再返回给Lua
luaL_newlib(L,mylib);
return 1;
}
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
const luaL_Reg *libf = mylib;
luaL_requiref(L,"my",luaopen_my,1);//1代表生成到全局作用域
luaL_dofile(L,"yy.lua");
lua_close(L);
}
//yy.lua
sum = my.add(1,2,3,4,5)
print(sum)
print(my.printhello())