一、Lua与C++的交互机制——Lua堆栈
1)交互机制
Lua和C++ 的交互机制的基础在于Lua提供了一个虚拟栈,C++ 和Lua之间的所有类型的数据交换都通过这个栈完成。无论何时C想从Lua中调用一个值,被请求的值将会被压入栈,无论何时C想要传递一个值给Lua,首先将整个值压栈,然后就可以在Lua中调用。
栈中每个元素都能保存任何类型的Lua值(实际上Lua的任何类型的值包括字符串、表等等,最终都是以TValue这种数据结构来保存的)
当在C代码中要获取Lua的一个值的时候,只需要调用Lua API将指定值压入栈中,C再获取栈值
API有一系列的压栈函数,为了将栈顶的Lua值转换成C值,我们为每种类型定义一个对应的函数:
void lua_pushnil(Lua_State *L);
void lua_pushboolean(Lua_State *L,int bool);
void lua_pushnumber(Lua_State *L,double n);
void lua_pushstring(Lua_State*L,const char*s);
void lua_pushuserdata(Lua_State*L,void*p);
API有一系列的从栈中获取值的函数,为了将栈中的转换C值成Lua值
bool lua_toboolean(Lua_State*L,int idx);
int lua_tonumber(Lua_State*L,int idx);
const char* lua_tostring(Lua_State*L,int idx,size_t *len);
void* lua_touserdata(Lua_State*L,int idx);
Lua API还提供了一套lua_is*来检查一个元素是否是一个指定的类型
int lua_isboolean(Lua_State*L,int idx);
int lua_isnumber(Lua_State*L,int idx);
int lua_isstring(Lua_State*L,int idx);
此外还提供了API函数来人工控制堆栈:
int lua_gettop(luaState *L);
void lua_settop(luaState *L,int idx);
void lua_pushvalue(luaState *L,int idx);
void lua_remove(luaState *L,int idx);
void lua_insert(luaState *L,int idx);
void lua_replace(luaState *L,int idx);
Lua API函数参照官方手册:http://www.lua.org/manual/5.3/
Lua中,对虚拟栈提供正向索引和反向索引两种索引方式,假设当前Lua的栈中有5个元素,如下图所示:
当C和Lua互相调用的时候,Lua虚拟栈严格的按照LIFO规则操作,只会改变栈顶部分。但通过Lua的API,可以查询栈上的任何元素,甚至是在任何一个位置插入和删除元素。
2)示例
以字符串和数字值为例试一下对Lua栈的操作
环境:IDE Clion
资源:Lua源文件包中除了lua.c和luac.c(这两个源文件中都有main函数,其中lua.c编译之后就是我们常用的lua.exe)的所有源文件 源文件下载地址
配置CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(luac)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp ltablib.c lauxlib.c lbaselib.c lapi.c lbitlib.c lcode.c lcorolib.c lctype.c ldblib.c ldebug.c ldo.c