lua-cpp绑定

sol2
这个目前看比较适合

lua 直接包含源码进来就可以了,不用编译成库。
下面是一个小例子

function sum(x, y)
return x + y
end
#include <lua/lua.hpp>

int LuaHelper::test(int x, int y)
{
string strErr;
lua_State* L = luaL_newstate();
if (luaL_loadfile(L, "sum.lua") || lua_pcall(L, 0, 0, 0)) {
strErr = "Error: failed to load sum.lua";
return 0;
}

lua_getglobal(L, "sum");
lua_pushnumber(L, x);
lua_pushnumber(L, y);

lua_pcall(L, 2, 1, 0);

int result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
return result;
}

读取 lua 数据

void lua_pushnil      (lua_State *L);
void lua_pushboolean (lua_State *L, int bool);
void lua_pushnumber (lua_State *L, lua_Number n);
void lua_pushinteger (lua_State *L, lua_Integer n);
void lua_pushlstring (lua_State *L, const char *s, size_t len);
void lua_pushstring (lua_State *L, const char *s);

全局变量

C 接口

int lua_getglobal (lua_State *L, const char *name);
Pushes onto the stack the value of the global name. Returns the type of that value.

void lua_setglobal (lua_State *L, const char *name);
Pops a value from the stack and sets it as the new value of global name.

cpp 读取 lua 表

if (lua_istable(m_luaState,-1))
{
// Push another reference to the table on top of the stack (so we know
// where it is, and this function can work for negative, positive and
// pseudo indices
lua_pushvalue(m_luaState, -1);
// stack now contains: -1 => table
lua_pushnil(m_luaState);
// stack now contains: -1 => nil; -2 => table
while (lua_next(m_luaState, -2))
{
// stack now contains: -1 => value; -2 => key; -3 => table
// copy the key so that lua_tostring does not modify the original
lua_pushvalue(m_luaState, -2);
// stack now contains: -1 => key; -2 => value; -3 => key; -4 => table
string strKey = lua_tostring(m_luaState, -1);
retVar = lua_tonumber(m_luaState, -2);
// pop value + copy of key, leaving original key
lua_pop(m_luaState, 2);
// stack now contains: -1 => key; -2 => table
}

}

栈操作

默认栈空间是 20 个。一般情况下都可以用。

可以使用下面函数检查栈空间是否可用。

-- 返回错误码
int lua_checkstack (lua_State *L, int sz);
-- 返回错误信息
void luaL_checkstack (lua_State *L, int sz, const char *msg);

第一个压栈的元素索引是 1,第二个是 2,以此类推。
引用栈顶元素是 -1,第二个是 -2, 以此类推。

lua_tostring(L, -1) 作为字符串返回栈顶元素

判断栈元素类型,使用一组 lua_is* 函数,* 可以是任何 lua 数据类型。例如:lua_isnil, lua_isnumber, lua_isstring, lua_istable

函数原型如下:
int lua_is* (lua_State *L, int index);

实际上 lua_isnumber 和 lua_isstring 检查的是,能否转换到指定类型。所以 任何数值类型满足字符串类型的判断。

还有个函数 lua_type 可以获取数据类型,每个数据类型都有常量定义:LUA_TNIL, LUA_TBOOLEAN, LUA_TNUMBER, LUA_TSTRING

获取元素个数

获取栈中的元素个数
int lua_gettop (lua_State *L);

放入数据

函数原型:lua_push*
放置 * 元素到栈顶

lua_pushboolean
lua_pushcclosure
lua_pushcfunction
lua_pushfstring
lua_pushinteger
lua_pushlightuserdata
lua_pushliteral
lua_pushlstring (arbitrary strings (char *))
lua_pushnil
lua_pushnumber (double)
lua_pushstring (zero-terminated strings)
lua_pushthread
lua_pushvalue
lua_pushvfstring

放入数组


// 建一个新表 栈高度+1, 栈顶元素是新table
// 创建一个新的table, 并把它放在栈顶. narr和nrec分别指定该table的array部分和hash部分的预分配元素数量
void lua_createtable (lua_State *L, int narr, int nrec)

// 用于设置table元素的方法
void lua_settable (lua_State *L, int index);
void lua_rawset (lua_State *L, int index);

void lua_setfield (lua_State *L, int index, const char *k);
void lua_rawseti (lua_State *L, int index, int n);

类型判断

函数原型:lua_is*

int lua_isstring(lua_State L, int index)
判断index指明位置上的元素是为对应的
类型,这里是string. 如果是则返回1,否则返回0;不会改变栈的大小,内容

获取数据

使用 lua_to* 函数。

int lua_toboolean (lua_State *L, int index);
const char *lua_tolstring (lua_State *L, int index, size_t *len);
lua_State *lua_tothread (lua_State *L, int index);
lua_Number lua_tonumber (lua_State *L, int index);
lua_Integer lua_tointeger (lua_State *L, int index);

lua_tolstring and lua_tothread return NULL for values with incorrect types.
The numeric functions, however, have no way to signal a wrong type, so they simply return zero.

引入的新函数:
lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum);
lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum);

The out parameter isnum returns a Boolean that indicates whether the Lua value was successfully coerced to the desired type.

int  lua_gettop    (lua_State *L);
void lua_settop (lua_State *L, int index);
void lua_pushvalue (lua_State *L, int index);
void lua_rotate (lua_State *L, int index, int n);
void lua_remove (lua_State *L, int index);
void lua_insert (lua_State *L, int index);
void lua_replace (lua_State *L, int index);
void lua_copy (lua_State *L, int fromidx, int toidx);

double LuaHelper::test_var()
{
double result = 0;
string strErr;

/* opens Lua */
lua_State* m_luaState = luaL_newstate();
/* opens the standard libraries */
luaL_openlibs(m_luaState);
if (luaL_loadfile(m_luaState, "sum.lua") || lua_pcall(m_luaState, 0, 0, 0)) {
strErr = lua_tostring(m_luaState, -1);
lua_pop(m_luaState, 1); /* pop error message from the stack */
}
else
{
double up_right1_min = 15.3456;
double up_left1_max = 10.1324;
double up_left1_mean = 10.12;
double down_left1_mean = 7.12;

lua_pushnumber(m_luaState, up_right1_min);
lua_setglobal(m_luaState, "up_right1_min");
lua_pushnumber(m_luaState, up_left1_max);
lua_setglobal(m_luaState, "up_left1_max");


// 获取函数,压入栈中
lua_getglobal(m_luaState, "solve_formula");
// 调用函数,调用完成以后,会将返回值压入栈中,2表示参数个数,1表示返回结果个数。
int iRet = lua_pcall(m_luaState, 0, 1, 0);
if (iRet)
{
// 调用出错
const char* pErrorMsg = lua_tostring(m_luaState, -1);

lua_close(m_luaState);
return -1;
}
if (lua_isnumber(m_luaState, -1)) //取值输出
{
result = lua_tonumber(m_luaState, -1);
string str = fmt::format("{}", result);
lua_pop(m_luaState, 1);
}

}
lua_close(m_luaState);
return result;
}