lua(7)-C API

Lua是一种嵌入式语言,支持被其他语言如C、C++调用,这时候lua被当成是一个c++的库,c++引用了这个库提供的c++接口,就能对lua脚本进行操作。lua提供了一个虚拟栈,与C、C++语言实现通信是在这个栈里面实现的,lua在这个虚拟栈内解决交互时内存释放方式的差异性(lua有垃圾回收机制,c和c++要求显式释放内存)、类型使用的差异性(C和C++使用静态类型,lua使用动态类型)。

首先我们需要知道,lua代码在执行的时候,保存的变量、程序块都是保存在一个“栈”中的,这个栈也称作lua的虚拟机,由lua的库提供。只有虚拟机环境打开了,lua代码才成执行。C API的作用就是,通过控制lua的虚拟机,来完成与lua代码的交互。

这个栈大概是这个样子的:


Lua的栈中栈顶的下标为-1,往下以此递减;栈底的下标为1,往上依次递增。

以下示例均为c++代码,新建一个.cpp文件就可以执行。

常用的一些C API有这些:

1、lua_State *luaL_newstate()

作用:用于创建一个新环境(或状态)。也就是创建一个lua虚拟机(栈),这个虚拟机(栈)被创建出来的时候没有包含预定义的函数,需要使用luaL_openlibs函数来打开标准库。

用法示例:

lua_State* L = luaL_newstate();


2、void luaL_openlibs(lua_State *L)

作用:打开所有的lua标准库。lua的设计者为了使lua保持小巧,所有的标准库都被组织到了不同的包中,头文件lualib.h中定义了打开这些库的函数,而辅助库函数luaL_openlibs则可以打开所有的标准库。

用法示例:

lua_State* L = luaL_newstate();
//打开标准库,这样状态机可以使用lua库函数,可以解释lua脚本
luaL_openlibs(L);


3、int luaL_loadbuffer(lua_State *L, const char *buff,size_t sz,const char *name)

作用:把buff当成lua代码加载,这个方法使用了lua_load函数,与lua_load一样,如果加载没有错误,这个函数将返回0,并向栈中压入编译后的程序块。通常这个函数用于调试信息和检查错误。

用法示例:

//用户输入
while(fgets(buff,sizeof(buff),stdin) != NULL)
{
    //接收用户输入的数据,编译为程序块并压入栈中,如果没有错误,返回0;如果有错误,压入一行错误信息的字符串
    int loadError =luaL_loadbuffer(L,buff,strlen(buff),"line");
}


4、int lua_pcall(lua_State *L, int nargs, intnresults, int errfunc)

作用:将程序块从栈中弹出,并在保护模式中运行它。参数1为栈的指针,参数2为想传入的参数的个数,参数3为想返回的结果的个数,参数4为运行错误时的错误处理函数索引,这个索引为栈里面的索引。如果运行没有错误,这个函数返回0;如果有错误,这个函数会向栈中压入一条错误消息,用lua_tostring可以获取这条消息。

用法示例:

lua_State* L = luaL_newstate();
luaL_openlibs(L);
char fileName[] = "F:/abc.lua";
//加载lua文件,解释器将lua文件的内容读取出来,动态编译为代码块
luaL_loadfile(L,fileName);
//执行编译好的代码块,参数1为栈指针,参数2为传给待调用函数的参数数量,
//参数3为期望返回的结果的数量,参数4为错误处理函数的索引
int result = lua_pcall(L,0,LUA_MULTRET,0);
//如果运行没有错误,lua_pcall将返回0
if(!result)
{
    printf_s("lua脚本运行成功\n");
}


5、lua_tostring、const char *lua_tolstring(lua_State *L, int idx, size_t *len)

作用:把栈中指定索引处的值转化为C字符串并返回这个字符串,这个值只能是字符串或数字,否则lua会抛出异常;返回的字符串由于是C字符串,因此最后一个字符总是'\0'。如果设置了第三个参数len,这个函数还会修改并返回这个引用的*len。lua_tostring等价于lua_tolstring,只是把第三个参数len设置成NULL。

用法示例:

lua_pushstring(L,"hello world");                 //向栈中压入字符串"hello world"
printf_s("%s\n",lua_tostring(L,-1));             //栈顶下标为-1,取出栈顶字符串,输出"hello world"
//注意不能写成size_t* strSize = 0; lua_tolstring(L,-1,strSize);
//因为C++的指针作为实参使用时,会拷贝一份值而不是引用
size_t strSize = 0;
printf_s("%s\n",lua_tolstring(L,-1,&strSize));   //"hello world"
printf_s("%d\n",strSize);                        //取得"hello world"的长度,输出11


6、#define lua_pop(L,n)

作用:将栈中的元素弹出(即删除栈中的元素),从栈顶开始计算弹出元素的个数。比如lua_pop(L,1)表示删除栈顶元素;lua_pop(L,2)表示删除栈顶元素和栈顶元素下一个元素;lua_pop(L,-1)表示删除栈里的全部元素。

用法示例:

//假设此时栈中为空
lua_pushstring(L,"s");
printf_s("%s\n",lua_tostring(L,-1));  //s
lua_pop(L,1);
printf_s("%s\n",lua_tostring(L,-1));  //(null)
 
lua_pushstring(L,"s2");
lua_pushnumber(L,123);
printf_s("%s\n",lua_tostring(L,-2));  //s2
lua_pop(L,2);
printf_s("%s\n",lua_tostring(L,-1));  //(null)
printf_s("%s\n",lua_tostring(L,-2));  //(null)


7、void lua_pushnil(lua_State *L)

作用:向栈中压入nil这个常量(压入空指针)。

用法示例:

//假设此时栈中为空
lua_pushstring(L,"s");
if(LUA_TSTRING == lua_type(L,-1))
{
    printf_s("栈顶是字符串s");
}
 
lua_pushnil(L);
if(LUA_TNIL == lua_type(L,-1))
{
    printf_s("栈顶是nil");
}
//输出:栈顶是字符串s 栈顶是nil


8、void lua_pushnumber(lua_State *L, lua_Number n)

作用:向栈中压入双精度浮点数。对于压入整形、浮点数、双精度浮点数均有效。

用法示例:

//假设此时栈中为空
lua_pushnumber(L,1);
lua_pushnumber(L,1.23);
lua_pushnumber(L,1.234567);
 
printf_s("%g\n",lua_tonumber(L,-1));   //1.234567
printf_s("%g\n",lua_tonumber(L,-2));   //1.23
printf_s("%g\n",lua_tonumber(L,-3));   //1


9、void lua_pushinteger(lua_State *L, lua_Integer n)

作用:向栈中压入整数。返回的是lua_Number类型,如果使用%d格式化输出,得转成int格式。

用法示例:

//假设此时栈中为空
lua_pushinteger(L,1);
lua_pushinteger(L,2);
lua_pushinteger(L,3);
 
printf_s("%d\n",(int)lua_tonumber(L,-1));//3
printf_s("%d\n",(int)lua_tonumber(L,-2));//2
printf_s("%d\n",(int)lua_tonumber(L,-3));//1


10、void lua_pushlstring(lua_State *L, const char *s,size_t l)

作用:向栈中压入字符串。lua会对传入的const char*s生成一个副本并使用它,不会对原字符串做修改。

用法示例:

//假设此时栈中为空
lua_pushstring(L,"s1");
lua_pushstring(L,"s2");
lua_pushstring(L,"s3");
lua_pushlstring(L,"s4",2);
lua_pushlstring(L,"s10",3);
 
printf_s("%s\n",lua_tostring(L,-1)); //s10
printf_s("%s\n",lua_tostring(L,-2)); //s4
printf_s("%s\n",lua_tostring(L,-3)); //s3
printf_s("%s\n",lua_tostring(L,-4)); //s2
printf_s("%s\n",lua_tostring(L,-5)); //s1


11、void lua_pushstring(lua_State *L, const char *s)

作用:向栈中压入字符串,一般用于压入以\0结尾的字符串。lua会对传入的const char*s生成一个副本并使用它,不会对原字符串做修改。

用法示例:

//假设此时栈中为空
lua_pushstring(L,"s1");
lua_pushstring(L,"s2");
lua_pushstring(L,"s3");
lua_pushlstring(L,"s4",2);
lua_pushlstring(L,"s10",3);
 
printf_s("%s\n",lua_tostring(L,-1)); //s10
printf_s("%s\n",lua_tostring(L,-2)); //s4
printf_s("%s\n",lua_tostring(L,-3)); //s3
printf_s("%s\n",lua_tostring(L,-4)); //s2
printf_s("%s\n",lua_tostring(L,-5)); //s1


12、void lua_pushboolean(lua_State *L, int b)

作用:向栈中压入布尔值。在C中,0假1真,对于参数b,只要非0,压入的值lua都视为true;b为0则视为false。使用lua_toboolean返回的值中,只要当前的值不是false或nil,lua均视为true,即返回1;否则返回0;无效的索引参数也会返回0。

用法示例:

//假设此时栈中为空
lua_pushboolean(L,123);
lua_pushboolean(L,0);
lua_pushboolean(L,2);
lua_pushboolean(L,-2);
lua_pushboolean(L,1);
lua_pushboolean(L,-1);
 
printf_s("%d\n",lua_toboolean(L,-1)); //1
printf_s("%d\n",lua_toboolean(L,-2)); //1
printf_s("%d\n",lua_toboolean(L,-3)); //1
printf_s("%d\n",lua_toboolean(L,-4)); //1
printf_s("%d\n",lua_toboolean(L,-5)); //0
printf_s("%d\n",lua_toboolean(L,-6)); //1


13、int lua_isnumber(lua_State *L, int idx)

作用:检查一个元素是否为数字类型。实际上是检查这个元素是否能转化为数字。如果这个元素为数字类型,返回1,否则返回0。

用法示例:

//假设此时栈中为空
lua_pushboolean(L,123);
lua_pushnumber(L,123);
lua_pushinteger(L,123);
 
if(lua_isnumber(L,-1))
    printf_s("The value in -1 is number.\n");
if(lua_isnumber(L,-2))
    printf_s("The value in -2 is number.\n");
if(lua_isnumber(L,-3))
    printf_s("The value in -3 is number.\n");
 
/*
The value in -1 is number.
The value in -2 is number.
*/


14、int lua_isstring(lua_State *L, int idx)

作用:检查一个元素是否为字符串类型,实际上是检查这个元素是否能转化为字符串。如果这个元素为字符串类型,返回1,否则返回0。

用法示例:

//假设此时栈中为空
lua_pushboolean(L,123);
lua_pushnumber(L,123);
lua_pushinteger(L,123);
lua_pushstring(L,"123");
 
if(lua_isstring(L,-1))
    printf_s("The value in -1 can convertted tostring.\n");
if(lua_isstring(L,-2))
    printf_s("The value in -2 can convertted tostring.\n");
if(lua_isstring(L,-3))
    printf_s("The value in -3 can convertted to string.\n");
if(lua_isstring(L,-4))
    printf_s("The value in -4 can convertted tostring.\n");
 
/*
The value in -1 can convertted to string.
The value in -2 can convertted to string.
The value in -3 can convertted to string.
*/


15、int lua_iscfunction(lua_State *L, int idx)

作用:检查一个元素是否为C函数类型。如果是C函数类型,返回1,否则返回0。

用法示例:

int fun1(lua_State* L)
{
    return 0;
}
//假设此时栈中为空
lua_pushboolean(L,123);
lua_pushnumber(L,123);
lua_pushstring(L,"123");
lua_pushcfunction(L,fun1);
 
if(lua_iscfunction(L,-1))
    printf_s("The value in -1 is cFunction.\n");
if(lua_iscfunction(L,-2))
    printf_s("The value in -2 is cFunction.\n");
if(lua_iscfunction(L,-3))
    printf_s("The value in -3 is cFunction.\n");
if(lua_iscfunction(L,-4))
    printf_s("The value in -4 is cFunction.\n");
 
/*
The value in -1 is cFunction.
*/


16、#define lua_isfunction(L,n) (lua_type(L, (n)) ==LUA_TFUNCTION)

作用:检查一个元素是否为函数类型,如果是C函数或Lua函数,返回1,否则返回0。

用法示例:

int fun1(lua_State* L)
{
    return 0;
}
//假设此时栈中为空
luaL_loadbuffer(L,"function myLuaFunc()end;",strlen("function myLuaFunc() end;"),"line");
int callError = lua_pcall(L,0,0,0);
if(callError)
{
    printf_s("callError\n");
    printf_s("%s\n",lua_tostring(L,-1));
    lua_pop(L,1);
}
lua_getglobal(L,"myLuaFunc");    //stack:myLuaFunc
lua_pushboolean(L,123);          //stack:myLuaFunc、123
lua_pushnumber(L,123);           //stack:myLuaFunc、123、123
lua_pushstring(L,"123");         //stack:myLuaFunc、123、123、123
lua_pushcfunction(L,fun1);       //stack:myLuaFunc、123、123、123、fun1
 
if(lua_isfunction(L,-1))
    printf_s("The value in -1 is function.\n");
if(lua_isfunction(L,-2))
    printf_s("The value in -2 is function.\n");
if(lua_isfunction(L,-3))
    printf_s("The value in -3 is function.\n");
if(lua_isfunction(L,-4))
    printf_s("The value in -4 is function.\n");
if(lua_isfunction(L,-5))
    printf_s("The value in -5 is function.\n");
 
/*
The value in -1 is function.
The value in -5 is function.
*/

17、int lua_isuserdata(lua_State *L, int idx)

作用:检查一个元素是否为userdata(用户自定义类型)类型。如果是userdata类型,返回1;否则返回0。

用法示例:

struct myStruct //自定义数据类型
{
    int age;
    string name;
};
enum myEnum //自定义数据类型
{
    a = 0,
    b = 1,
    c = 2
};
 
myStruct* struct1 = NULL;
myEnum* enum1 = NULL;
 
//假设此时栈中为空
lua_pushlightuserdata(L,struct1);      //stack:struct1
lua_pushlightuserdata(L,enum1);        //stack:struct1、enum1
lua_pushboolean(L,123);                //stack:struct1、enum1、123
lua_pushnumber(L,123);                 //stack:struct1、enum1、123、123
lua_pushstring(L,"123");               //stack:struct1、enum1、123、123、123
 
if(lua_isuserdata(L,-1))
    printf_s("The value in -1 is userdata.\n");
if(lua_isuserdata(L,-2))
    printf_s("The value in -2 is userdata.\n");
if(lua_isuserdata(L,-3))
    printf_s("The value in -3 is userdata.\n");
if(lua_isuserdata(L,-4))
    printf_s("The value in -4 is userdata.\n");
if(lua_isuserdata(L,-5))
    printf_s("The value in -5 is userdata.\n");
 
/*
The value in -4 is userdata.
The value in -5 is userdata.
*/


18、int lua_type(lua_State *L, int idx)

作用:获得栈中的一个元素的类型。每种类型都对应于一个常量,这些常量定义在头文件lua.h中,它们是LUA_TNIL、LUA_TBOOLEAN、LUA_TNUMBER、LUA_TSTRING、LUA_TTABLE、LUA_TTHREAD、LUA_TUSERDATA、LUA_TFUNCTION。

用法示例:

//假设此时栈中为空
lua_pushboolean(L,123);
lua_pushnumber(L,123);
lua_pushstring(L,"123");
 
if(LUA_TSTRING == lua_type(L,-1))
    printf_s("The value in -1 is string.\n");
if(LUA_TNUMBER == lua_type(L,-2))
    printf_s("The value in -2 is number.\n");
if(LUA_TBOOLEAN == lua_type(L,-3))
    printf_s("The value in -3 is boolean.\n");
 
/*
The value in -1 is string.
The value in -2 is number.
The value in -3 is boolean.
*/


19、lua_Number lua_tonumber(lua_State *L, int idx)

作用:检查栈中的一个元素是否为数字类型,如果不是,将返回0;如果是,将返回这个数字的值。实际上,这个函数会检查当前这个元素是否能转化成数字类型,如果可以就返回这个转化后的数字,否则返回0。

用法示例:

//假设此时栈中为空
lua_pushboolean(L,123);
lua_pushnumber(L,123);
lua_pushinteger(L,12);
lua_pushstring(L,"123");
lua_pushstring(L,"123C");
 
printf_s("%g\n",lua_tonumber(L,-1)); //0
printf_s("%g\n",lua_tonumber(L,-2)); //123
printf_s("%g\n",lua_tonumber(L,-3)); //12
printf_s("%g\n",lua_tonumber(L,-4)); //123
printf_s("%g\n",lua_tonumber(L,-5)); //0


20、lua_Integer lua_tointeger(lua_State *L, int idx)

作用:检查栈中的一个元素是否为整数类型,如果不是,将返回0;如果是,将返回这个整数的值。实际上,这个函数会检查当前元素是否能转化成整数类型,对于浮点数,lua_tointeger将会采用四舍五入的方式进行转化;如果当前的值转化成功,返回1,否则返回0。

用法示例:

//假设此时栈中为空
lua_pushboolean(L,123);
lua_pushnumber(L,123.7);
lua_pushnumber(L,123.1);
lua_pushinteger(L,12);
lua_pushstring(L,"123");
lua_pushstring(L,"123C");
 
printf_s("%d\n",(int)lua_tointeger(L,-1));//0
printf_s("%d\n",(int)lua_tointeger(L,-2));//123
printf_s("%d\n",(int)lua_tointeger(L,-3));//12
printf_s("%d\n",(int)lua_tointeger(L,-4));//123
printf_s("%d\n",(int)lua_tointeger(L,-5));//124
printf_s("%d\n",(int)lua_tointeger(L,-6));//0


21、int lua_toboolean(lua_State *L, int idx)

作用:检查栈中一个元素是否为布尔类型,如果不是,返回0,否则返回1。实际上,只要idx处的元素不是false或nil,lua_toboolean都会返回1,否则返回0。

用法示例:

//假设此时栈中为空
lua_pushboolean(L,0);
lua_pushnumber(L,123.1);
lua_pushnil(L);
lua_pushstring(L,"123");
 
printf_s("%d\n",lua_toboolean(L,-1)); //1
printf_s("%d\n",lua_toboolean(L,-2)); //0
printf_s("%d\n",lua_toboolean(L,-3)); //1
printf_s("%d\n",lua_toboolean(L,-4)); //0


22、const char *lua_tolstring(lua_State *L, int idx, size_t*len)

作用:检查栈中一个元素是否为字符串类型,如果不是,返回NULL;如果是,返回这个字符串的值。


23、int lua_gettop(lua_State *L)

作用:返回栈中元素的个数,也可以说是栈顶元素的索引(栈底的索引是1)。

用法示例:

//假设此时栈中为空
printf_s("Number of stackelements:%d\n",lua_gettop(L)); //0
lua_pushboolean(L,0);
lua_pushnumber(L,123.1);
printf_s("Number of stackelements:%d\n",lua_gettop(L)); //2
lua_pop(L,1);
printf_s("Number of stackelements:%d\n",lua_gettop(L)); //1


24、void lua_settop(lua_State *L, int idx)

作用:将栈顶设置为一个指定的位置,即修改栈中元素的数量。如果之前的栈顶比新设置的更高,那么高出来的这些元素会被丢弃;反之,会向栈中压入nil。调用lua_settop(L,0)能清空栈。也可以用负数索引来使用lua_settop。另外,API根据这个函数还提供了一个宏,用于从栈中弹出n个元素,#define lua_pop(L,n)lua_settop(L,-(n)-1)。

用法示例:

//假设此时栈中为空
lua_pushboolean(L,0);
lua_pushnumber(L,123.1);
lua_pushnil(L);
lua_pushstring(L,"123");
printf_s("Number of stackelements:%d\n",lua_gettop(L)); //4
lua_settop(L,2);
printf_s("Number of stackelements:%d\n",lua_gettop(L)); //2
lua_settop(L,-4);
printf_s("Number of stackelements:%d\n",lua_gettop(L)); //-1
lua_settop(L,-2);
printf_s("Number of stackelements:%d\n",lua_gettop(L)); //-2
lua_pushstring(L,"123");
printf_s("Number of stackelements:%d\n",lua_gettop(L)); //-1


25、void lua_pushvalue(lua_State *L, int idx)

作用:将指定索引的值的副本压入栈。比如lua_pushvalue(L,1)会把栈底元素拷贝一个副本,然后将这个副本压入栈。

用法示例:

//假设此时栈中为空
lua_pushboolean(L,0);
lua_pushnumber(L,123.1);
lua_pushstring(L,"ABC");
//把栈顶处的"ABC"拷贝一份压入栈
lua_pushvalue(L,-1);
 
printf_s("%s\n",lua_tostring(L,-1));  //ABC
printf_s("%s\n",lua_tostring(L,-2));  //ABC
printf_s("%g\n",lua_tonumber(L,-3));  //123.1
printf_s("%d\n",lua_toboolean(L,-4)); //0


26、void lua_remove(lua_State *L, int idx)

作用:删除指定索引的元素,并将该位置之上的所有元素下移以填补空缺。

用法示例:

//假设此时栈中为空
lua_pushstring(L,"hello world");
lua_pushstring(L,"hi");
lua_pushstring(L,"ABC");
 
printf_s("%s\n",lua_tostring(L,-1)); //ABC
printf_s("%s\n",lua_tostring(L,-2)); //hi
printf_s("%s\n",lua_tostring(L,-3)); //helloworld
 
lua_remove(L,-2);
 
printf_s("%s\n",lua_tostring(L,-1)); //ABC
printf_s("%s\n",lua_tostring(L,-2)); //helloworld


27、void lua_insert(lua_State *L, int idx)

作用:会上移指定位置之上的所有元素以开辟一个槽的空间,然后将栈顶元素移到该位置。

用法示例:

//假设此时栈中为空
lua_pushstring(L,"hello world");
lua_pushstring(L,"hi");
lua_pushstring(L,"ABC");
//此时栈顶是ABC
printf_s("%s\n",lua_tostring(L,-1)); //ABC
printf_s("%s\n",lua_tostring(L,-2)); //hi
printf_s("%s\n",lua_tostring(L,-3)); //helloworld
//在-2的位置开辟一个新位置,将-2之上的元素上移,将栈顶移到-2处
lua_insert(L,-2);
 
printf_s("%s\n",lua_tostring(L,-1)); //hi
printf_s("%s\n",lua_tostring(L,-2)); //ABC
printf_s("%s\n",lua_tostring(L,-3)); //helloworld


28、void lua_replace(lua_State *L, int idx)

作用:弹出栈顶的值,并将该值设置到指定的索引上,但它不会移动任何东西。

用法示例:

//假设此时栈中为空
lua_pushstring(L,"hello world");
lua_pushstring(L,"hi");
lua_pushstring(L,"ABC");
//此时栈顶是ABC
printf_s("%s\n",lua_tostring(L,-1)); //ABC
printf_s("%s\n",lua_tostring(L,-2)); //hi
printf_s("%s\n",lua_tostring(L,-3)); //helloworld
//弹出栈顶的元素将其移动到-2处
lua_replace(L,-2);
 
printf_s("%s\n",lua_tostring(L,-1)); //ABC
printf_s("%s\n",lua_tostring(L,-2)); //helloworld
printf_s("%s\n",lua_tostring(L,-3));//(null)


29、#define lua_getglobal(L,s) lua_getfield(L,LUA_GLOBALSINDEX, (s))

作用:lua_getglobal是一个宏,这个宏第2个参数是char* ,每次调用这个宏都会把这个全局变量值压入栈中。比如文件或lua文件中有这样一段代码:

      a = 1

      b = "hello world"

然后在cpp中这么写:

      lua_getglobal(L,"a");

      lua_getglobal(L,"b");

这样栈底就是a的值,a上面是b的值。可以通过lua_tointeger(L,1)、lua_tolstring(L,2,NULL)来获取它们的值来验证。

s这个全局变量得在代码块被执行后才能被找到。

用法示例:

//假设此时栈中为空
luaL_loadbuffer(L,"str = 'I amString'",strlen("str = 'I am String'"),"line");
int callError = lua_pcall(L,0,0,0);
if(callError)
{
    printf_s("%s",lua_tostring(L,-1));
    lua_pop(L,1);
}
lua_pushstring(L,"hello world");
lua_pushstring(L,"hi");
lua_pushstring(L,"ABC");
//此时栈顶是ABC
printf_s("%s\n",lua_tostring(L,-1)); //ABC
printf_s("%s\n",lua_tostring(L,-2)); //hi
printf_s("%s\n",lua_tostring(L,-3)); //helloworld
//获得str这个字段的值,并将其压桟
lua_getglobal(L,"str");
 
printf_s("%s\n",lua_tostring(L,-1)); //I amString
printf_s("%s\n",lua_tostring(L,-2)); //ABC
printf_s("%s\n",lua_tostring(L,-3)); //hi
printf_s("%s\n",lua_tostring(L,-4)); //helloworld


30、int luaL_loadfile (lua_State *L, const char*filename)

作用:从指定目录的文件中加载代码块。这个文件可以是文本文件,也可以是.lua文件,只要文本内容是lua代码就可以。如果加载文件成功,返回0,否则返回非0,同时向栈中压入一条错误信息。

比如test.txt文件和test.lua文件,只要路径正确,这里面的文本内容都会被执行。

用法示例:

lua_State* L = luaL_newstate();
luaL_openlibs(L);
char fileName[] = "F:/abc.lua";
luaL_loadfile(L,fileName);
int result = lua_pcall(L,0,LUA_MULTRET,0);
if(!result)
{
    printf_s("lua脚本运行成功\n");
}


31、void lua_gettable(lua_State *L, int idx)

作用:从位于idx处的表t中取出t[k]并压桟,其中k是处于栈顶的key。

用法示例:

//假设配置文件写的是tbl = {a=3,b=2,c=4}
luaL_loadbuffer(L,"tbl ={a=3,b=2,c=4}",strlen("tbl = {a=3,b=2,c=4}"),"line");
int callError = lua_pcall(L,0,0,0);
if(callError)
{
    printf_s("%s",lua_tostring(L,-1));
    lua_pop(L,1);
}
//此时栈中为空,取得tbl的值,压入栈中
lua_getglobal(L,"tbl");        //stack:tbl
if(!lua_istable(L,-1))
{
    printf_s("the top of stack not a table.\n");
    return 0;
}
//压入要索引的key
lua_pushstring(L,"a");               //stack:tbl、a
//tbl在-2位置,取得tbl[a],弹出a
lua_gettable(L,-2);                  //stack:tbl、3
printf_s("%g\n",lua_tonumber(L,-1));
lua_pop(L,1);
lua_pushstring(L,"b");               //stack:tbl、b
lua_gettable(L,-2);                  //stack:tbl、2
printf_s("%g\n",lua_tonumber(L,-1));
 
lua_pop(L,1);
lua_pushstring(L,"c");               //stack:tbl、c
lua_gettable(L,-2);                  //stack:tbl、4
printf_s("%g\n",lua_tonumber(L,-1));
 
/*
输出:
3
2
4
*/


32、int lua_gettop(lua_State *L)

作用:获得栈顶元素的正向索引,也就是获得栈中元素的个数。

用法示例:

//假设此时栈中为空
lua_pushstring(L,"hello world");
printf_s("%d\n",lua_gettop(L)); //1
lua_pushstring(L,"hi");
printf_s("%d\n",lua_gettop(L)); //2
lua_pushstring(L,"ABC");
printf_s("%d\n",lua_gettop(L)); //3
lua_pop(L,2);
printf_s("%d\n",lua_gettop(L)); //1


33、size_t lua_objlen(lua_State *L, int idx)

作用:获取栈中索引为idx处的对象的长度。如果idx处的元素为字符串,则返回字符串的长度;如果idx处的元素为table,则返回table的长度,等同于#table;如果idx处的元素是userdata,则返回压入userdata前为其分配的内存长度;如果idx处的元素是number,将返回这个number的有效位数,包括小数点;如果idx处的元素是其他类型,则返回0。

用法示例:

//假设此时栈中为空
luaL_loadbuffer(L,"tbl ={[1]=3,[2]=2,[3]=4}",strlen("tbl ={[1]=3,[2]=2,[3]=4}"),"line");
int callError = lua_pcall(L,0,0,0);
if(callError)
{
    printf_s("%s",lua_tostring(L,-1));
    lua_pop(L,1);
}
lua_getglobal(L,"tbl");
printf_s("table长度为:%d\n",(int)lua_objlen(L,-1));                //3
lua_pushstring(L,"hello world");
printf_s("string长度为:%d\n",(int)lua_objlen(L,-1));               //11
lua_pushnumber(L,12345678.90);
printf_s("num的有效位数(包括小数点):%d\n",(int)lua_objlen(L,-1));  //10
lua_pushboolean(L,99);
printf_s("bool长度为:%d\n",(int)lua_objlen(L,-1));                 //0


34、void lua_getfield(lua_State *L, int idx, constchar *k)

作用:获取table中指定的值,这个函数是lua_gettable的一个特化版本。比如知道了key后,可以使用lua_getfield(L,-1,key)来获取栈顶table索引为key的值。

用法示例:

//假设配置文件写的是tbl = {a=3,b=2,c=4}
luaL_loadbuffer(L,"tbl ={a=3,b=2,c=4}",strlen("tbl = {a=3,b=2,c=4}"),"line");
int callError = lua_pcall(L,0,0,0);
if(callError)
{
    printf_s("%s",lua_tostring(L,-1));
    lua_pop(L,1);
}
//此时栈中为空,取得tbl的值,压入栈中
lua_getglobal(L,"tbl");       //stack:tbl
if(!lua_istable(L,-1))
{
    printf_s("the top of stack not a table.\n");
    return 0;
}
lua_getfield(L,-1,"a");
printf_s("%g\n",lua_tonumber(L,-1));
lua_pop(L,1);
lua_getfield(L,-1,"b");
printf_s("%g\n",lua_tonumber(L,-1));
 
lua_pop(L,1);
lua_getfield(L,-1,"c");
printf_s("%g\n",lua_tonumber(L,-1));
 
/*
输出:
3
2
4
*/


35、#define luaL_checkstring(L,n) (luaL_checklstring(L, (n),NULL))

作用:检查当前被调用的函数的第n个参数是否是字符串,并返回这个字符串,同时还会把这个字符串压入栈顶。注意这里的n不是栈的索引,而是当前被调用方法的第n个参数。

用法示例:

int fun1(lua_State* L)
{
    const char* param1 = luaL_checkstring(L,1);
    const char* param2 = luaL_checkstring(L,2);
    printf_s("参数1为:%s\n",param1);
    printf_s("参数2为:%s\n",param2);
    return 0;
}
//压入fun1函数
lua_pushcfunction(L,fun1);
//给fun1函数设置一个变量作为索引,将这个变量设置到全局变量中,并弹出fun1
lua_setglobal(L,"fun1");
//在lua代码块中调用c代码中的fun1函数,并传入参数1和9
luaL_loadbuffer(L,"fun1(1,9)",strlen("fun1(1,9)"),"line");
int callError = lua_pcall(L,0,0,0);
if(callError)
{
    printf_s("%s",lua_tostring(L,-1));
    lua_pop(L,1);
}


35、#define lua_pushcfunction(L,f)lua_pushcclosure(L, (f), 0)

作用:向栈中压入c代码中的函数,参数f是一个函数指针。

用法示例:

int fun1(lua_State* L)
{
    return 0;
}
lua_pushcfunction(L,fun1);


36、void lua_rawget(lua_State *L, int idx)

作用:类似于 lua_gettable,但是作一次直接访问(不触发元方法)。

用法示例:

//假设配置文件写的是tbl = {a=3,b=2,c=4}
luaL_loadbuffer(L,"tbl ={a=3,b=2,c=4}",strlen("tbl = {a=3,b=2,c=4}"),"line");
int callError = lua_pcall(L,0,0,0);
if(callError)
{
    printf_s("%s",lua_tostring(L,-1));
    lua_pop(L,1);
}
//此时栈中为空,取得tbl的值,压入栈中
lua_getglobal(L,"tbl"); //stack:tbl
if(!lua_istable(L,-1))
{
    printf_s("the top of stack not a table.\n");
    return 0;
}
//压入要索引的key
lua_pushstring(L,"a");           //stack:tbl、a
//tbl在-2位置,取得tbl[a],弹出a
lua_rawget(L,-2);                //stack:tbl、3
printf_s("%g\n",lua_tonumber(L,-1));
lua_pop(L,1);
lua_pushstring(L,"b");           //stack:tbl、b
lua_rawget(L,-2);                //stack:tbl、2
printf_s("%g\n",lua_tonumber(L,-1));
 
lua_pop(L,1);
lua_pushstring(L,"c");           //stack:tbl、c
lua_rawget(L,-2);                //stack:tbl、4
printf_s("%g\n",lua_tonumber(L,-1));
 
/*
输出:
3
2
4
*/


37、void lua_rawgeti(lua_State *L, int idx, int n)

作用:把 t[n] 的值压栈,这里的t是指给定索引index处的一个值。 这是一个直接访问,不会触发元方法。

用法示例:

//假设配置文件写的是tbl = {[1]=99,[2]=200,[3]=423}
luaL_loadbuffer(L,"tbl ={[1]=99,[2]=200,[3]=423}",strlen("tbl ={[1]=99,[2]=200,[3]=423}"),"line");
int callError = lua_pcall(L,0,0,0);
if(callError)
{
    printf_s("%s",lua_tostring(L,-1));
    lua_pop(L,1);
}
//此时栈中为空,取得tbl的值,压入栈中
lua_getglobal(L,"tbl"); //stack:tbl
if(!lua_istable(L,-1))
{
    printf_s("the top of stack not a table.\n");
    return 0;
}
//取出tbl的第一个元素
lua_rawgeti(L,-1,1);
printf_s("%g\n",lua_tonumber(L,-1));
 
//弹出刚刚压入的第一个元素
lua_pop(L,1);
//取出tbl的第二个元素
lua_rawgeti(L,-1,2);
printf_s("%g\n",lua_tonumber(L,-1));
 
//弹出刚刚压入的第二个元素
lua_pop(L,1);
//取出tbl的第三个元素
lua_rawgeti(L,-1,3);
printf_s("%g\n",lua_tonumber(L,-1));
 
/*
输出:
99
200
423
*/


38、int luaL_ref(lua_State *L, int t)

作用:在索引为t处的table中为栈顶元素建立一个索引值,这个索引值是唯一的。这个函数通常用于快速为一些变量快速建立一个唯一的ID值,使用这个函数我们就不需要手动创建一个table和手动创建ID了。可以使用lua_rawgeti(L,t,r)来检索设置的值;可以使用luaL_unref这个函数来释放一个元素的索引值。lua提供了一个预设好的table,这个table专门用来提供给给变量注册,使用"LUA_REGISTRYINDEX"这个预设好的字段可以找到这个table。

用法示例:

lua_pushstring(L,"interesting");
luaL_ref(L,LUA_REGISTRYINDEX);  //为"interesting"注册索引号,由于是第一个注册,索引号为1
lua_pushnumber(L,1.234);
luaL_ref(L,LUA_REGISTRYINDEX);  //为1.234注册索引号,索引号为2
lua_pushinteger(L,988);
luaL_ref(L,LUA_REGISTRYINDEX);  //为988注册索引号,索引号为3
 
 
lua_rawgeti(L,LUA_REGISTRYINDEX,1);
printf_s("%s\n",lua_tostring(L,-1));   //interesting
lua_rawgeti(L,LUA_REGISTRYINDEX,2);
printf_s("%g\n",lua_tonumber(L,-1));   //1.234
lua_rawgeti(L,LUA_REGISTRYINDEX,3);
printf_s("%d\n",lua_tointeger(L,-1));  //988


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值