Lua C API 常用接口函数总结

Lua C API 常用接口函数总结

本文档总结了Lua C API中所有常用的接口函数,按功能领域分类,包含API名称、作用描述和典型用法示例。

1. 栈操作

lua_gettop

  • API 名称: int lua_gettop (lua_State *L)
  • 作用描述: 获取栈中元素的数量(栈顶索引)。常用于检查栈状态和调试。
  • 典型用法示例:
1
2
int n = lua_gettop(L); // 获取栈顶位置
printf("栈中有 %d 个元素\n", n);

lua_settop

  • API 名称: void lua_settop (lua_State *L, int index)
  • 作用描述: 设置栈顶位置。如果index小于当前栈顶,则截断栈;如果大于当前栈顶,则用nil填充。
  • 典型用法示例:
1
2
lua_settop(L, 0); // 清空栈
lua_settop(L, 3); // 确保栈至少有三个元素

lua_pushvalue

  • API 名称: void lua_pushvalue (lua_State *L, int index)
  • 作用描述: 将栈中指定索引的元素复制一份并压入栈顶。
  • 典型用法示例:
1
lua_pushvalue(L, -1); // 复制栈顶元素

lua_remove

  • API 名称: void lua_remove (lua_State *L, int index)
  • 作用描述: 移除栈中指定索引的元素,其后的元素向前移动。
  • 典型用法示例:
1
lua_remove(L, 2); // 移除索引为2的元素

lua_insert

  • API 名称: void lua_insert (lua_State *L, int index)
  • 作用描述: 将栈顶元素移动到指定索引位置,其他元素向后移动。
  • 典型用法示例:
1
lua_insert(L, 1); // 将栈顶元素移动到索引1处

lua_replace

  • API 名称: void lua_replace (lua_State *L, int index)
  • 作用描述: 将栈顶元素替换栈中指定索引的元素,然后弹出栈顶。
  • 典型用法示例:
1
lua_replace(L, 1); // 用栈顶元素替换索引1的元素

lua_checkstack

  • API 名称: int lua_checkstack (lua_State *L, int n)
  • 作用描述: 检查栈是否有足够的空间容纳n个元素,必要时扩展栈。
  • 典型用法示例:
1
2
3
if (!lua_checkstack(L, 5)) {
printf("无法扩展栈空间\n");
}

2. 数据类型判断与转换

lua_is*

  • API 名称: int lua_isnumber (lua_State *L, int index), int lua_isstring (lua_State *L, int index), int lua_istable (lua_State *L, int index), int lua_isnil (lua_State *L, int index), int lua_isboolean (lua_State *L, int index), int lua_isfunction (lua_State *L, int index), int lua_isuserdata (lua_State *L, int index), int lua_islightuserdata (lua_State *L, int index), int lua_isthread (lua_State *L, int index)
  • 作用描述: 判断栈中指定索引位置的值是否为指定类型。
  • 典型用法示例:
1
2
3
4
5
6
if (lua_isnumber(L, 1)) {
printf("索引1处的值是数字\n");
}
if (lua_isstring(L, -1)) {
printf("栈顶是字符串\n");
}

lua_type

  • API 名称: int lua_type (lua_State *L, int index)
  • 作用描述: 返回栈中值的类型代码(LUA_TNIL, LUA_TNUMBER, LUA_TSTRING等)。
  • 典型用法示例:
1
2
3
4
5
6
7
int type = lua_type(L, 1);
switch(type) {
case LUA_TNIL: printf("nil"); break;
case LUA_TNUMBER: printf("number"); break;
case LUA_TSTRING: printf("string"); break;
// ...
}

lua_typename

  • API 名称: const char * lua_typename (lua_State *L, int tp)
  • 作用描述: 根据类型代码返回类型的名称字符串。
  • 典型用法示例:
1
2
const char* type_name = lua_typename(L, lua_type(L, 1));
printf("类型: %s\n", type_name);

lua_tonumber

  • API 名称: lua_Number lua_tonumber (lua_State *L, int index)
  • 作用描述: 将栈中指定位置的数值转换为lua_Number类型。
  • 典型用法示例:
1
2
3
4
lua_Number num = lua_tonumber(L, 1);
if (lua_isnumber(L, 1)) {
printf("数值: %.2f\n", num);
}

lua_tointeger

  • API 名称: lua_Integer lua_tointeger (lua_State *L, int index)
  • 作用描述: 将栈中指定位置的数值转换为lua_Integer类型。
  • 典型用法示例:
1
2
lua_Integer int_val = lua_tointeger(L, 2);
printf("整数: %lld\n", int_val);

lua_tostring

  • API 名称: const char * lua_tostring (lua_State *L, int index)
  • 作用描述: 将栈中指定位置的字符串转换为C字符串。
  • 典型用法示例:
1
2
3
4
const char* str = lua_tostring(L, -1);
if (lua_isstring(L, -1)) {
printf("字符串: %s\n", str);
}

lua_toboolean

  • API 名称: int lua_toboolean (lua_State *L, int index)
  • 作用描述: 将栈中指定位置的布尔值转换为C语言布尔值。
  • 典型用法示例:
1
2
int bool_val = lua_toboolean(L, 1);
printf("布尔值: %s\n", bool_val ? "true" : "false");

lua_touserdata

  • API 名称: void * lua_touserdata (lua_State *L, int index)
  • 作用描述: 获取栈中userdata的指针。
  • 典型用法示例:
1
2
3
4
struct MyData* data = (struct MyData*)lua_touserdata(L, 1);
if (data) {
// 使用data
}

3. 全局变量与表操作

lua_getglobal

  • API 名称: void lua_getglobal (lua_State *L, const char *name)
  • 作用描述: 将全局变量name的值压入栈顶。
  • 典型用法示例:
1
2
lua_getglobal(L, "print"); // 获取全局函数print
lua_getglobal(L, "VERSION"); // 获取全局变量VERSION

lua_setglobal

  • API 名称: void lua_setglobal (lua_State *L, const char *name)
  • 作用描述: 将栈顶元素弹出并设置为全局变量name。
  • 典型用法示例:
1
2
lua_pushstring(L, "Hello World");
lua_setglobal(L, "greeting"); // 设置全局变量greeting = "Hello World"

lua_gettable

  • API 名称: void lua_gettable (lua_State *L, int index)
  • 作用描述: 将table[index][key]的值压入栈顶,其中key是栈顶元素。
  • 典型用法示例:
1
lua_getfield(L, -1, "key"); // 获取table中的字段(更常用)

lua_settable

  • API 名称: void lua_settable (lua_State *L, int index)
  • 作用描述: 设置table[index][key] = value,其中key是栈顶-1位置,value是栈顶位置。
  • 典型用法示例:
1
2
3
lua_pushstring(L, "key");
lua_pushstring(L, "value");
lua_settable(L, -3); // table[-3]["key"] = "value"

lua_getfield

  • API 名称: void lua_getfield (lua_State *L, int index, const char *k)
  • 作用描述: 将table[index][k]的值压入栈顶。
  • 典型用法示例:
1
2
lua_getfield(L, LUA_GLOBALSINDEX, "print"); // 获取全局表中的print函数
lua_getfield(L, -1, "length"); // 获取当前栈顶表的length字段

lua_setfield

  • API 名称: void lua_setfield (lua_State *L, int index, const char *k)
  • 作用描述: 设置table[index][k] = value(栈顶元素),然后弹出栈顶。
  • 典型用法示例:
1
2
lua_pushstring(L, "Hello");
lua_setfield(L, -2, "message"); // 设置表的message字段为"Hello"

lua_rawget

  • API 名称: void lua_rawget (lua_State *L, int index)
  • 作用描述: 类似lua_gettable,但不触发元方法。
  • 典型用法示例:
1
lua_rawget(L, LUA_GLOBALSINDEX); // 直接获取全局表,不触发元方法

lua_rawset

  • API 名称: void lua_rawset (lua_State *L, int index)
  • 作用描述: 类似lua_settable,但不触发元方法。
  • 典型用法示例:
1
lua_rawset(L, LUA_GLOBALSINDEX); // 直接设置全局表,不触发元方法

lua_newtable

  • API 名称: void lua_newtable (lua_State *L)
  • 作用描述: 创建一个空表并压入栈顶。
  • 典型用法示例:
1
2
lua_newtable(L); // 创建新表
lua_setglobal(L, "config"); // 将表设置为全局变量config

lua_createtable

  • API 名称: void lua_createtable (lua_State *L, int narr, int nrec)
  • 作用描述: 创建指定大小的表(narr个数组元素,nrec个哈希元素)并压入栈顶。
  • 典型用法示例:
1
lua_createtable(L, 10, 5); // 创建预分配10个数组槽位、5个哈希槽位的表

lua_getmetatable

  • API 名称: int lua_getmetatable (lua_State *L, int index)
  • 作用描述: 将对象index的元表压入栈顶,失败返回0。
  • 典型用法示例:
1
2
3
4
5
if (lua_getmetatable(L, 1)) {
// 获取到了元表
lua_getfield(L, -1, "__index");
// ...
}

lua_setmetatable

  • API 名称: int lua_setmetatable (lua_State *L, int index)
  • 作用描述: 将栈顶元素设置为对象index的元表,然后弹出栈顶。
  • 典型用法示例:
1
2
3
4
5
lua_newtable(L); // 创建元表
lua_pushstring(L, "__tostring");
lua_pushcfunction(L, my_tostring);
lua_settable(L, -3);
lua_setmetatable(L, -2); // 为栈顶表设置元表

4. C函数注册与调用

lua_pushcfunction

  • API 名称: void lua_pushcfunction (lua_State *L, lua_CFunction f)
  • 作用描述: 将C函数压入栈顶,使其可以作为Lua函数调用。
  • 典型用法示例:
1
2
3
4
5
6
7
static int my_function(lua_State *L) {
// C函数实现
return 0; // 返回值个数
}

lua_pushcfunction(L, my_function); // 注册C函数
lua_setglobal(L, "myFunc"); // 设置为全局函数

lua_register

  • API 名称: void lua_register (lua_State *L, const char *n, lua_CFunction f)
  • 作用描述: 将C函数注册为全局Lua函数(等于getglobal + pushcfunction + setglobal)。
  • 典型用法示例:
1
2
3
4
5
6
static int hello(lua_State *L) {
printf("Hello from C!\n");
return 0;
}

lua_register(L, "hello", hello); // 注册为全局函数hello

lua_pcall

  • API 名称: int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc)
  • 作用描述: 以安全模式调用函数,捕获错误。
  • 典型用法示例:
1
2
3
4
5
6
lua_getglobal(L, "myFunc"); // 获取要调用的函数
lua_pushstring(L, "parameter"); // 压入参数
if (lua_pcall(L, 1, 1, 0) != 0) { // 调用函数(1个参数,期望1个返回值)
printf("错误: %s\n", lua_tostring(L, -1));
lua_pop(L, 1); // 弹出错误信息
}

lua_call

  • API 名称: void lua_call (lua_State *L, int nargs, int nresults)
  • 作用描述: 直接调用函数,不处理错误(较危险,但速度快)。
  • 典型用法示例:
1
2
3
lua_getglobal(L, "print");
lua_pushstring(L, "Hello World");
lua_call(L, 1, 0); // 调用print函数

lua_getupvalue

  • API 名称: const char * lua_getupvalue (lua_State *L, int funcindex, int n)
  • 作用描述: 获取函数funcindex的第n个upvalue的名称和值。
  • 典型用法示例:
1
2
3
4
5
lua_getglobal(L, "myFunc");
const char* name = lua_getupvalue(L, -1, 1);
if (name) {
printf("Upvalue名称: %s\n", name);
}

lua_setupvalue

  • API 名称: const char * lua_setupvalue (lua_State *L, int funcindex, int n)
  • 作用描述: 设置函数funcindex的第n个upvalue。
  • 典型用法示例:
1
2
3
lua_getglobal(L, "myFunc");
lua_pushstring(L, "upvalue_value");
lua_setupvalue(L, -2, 1); // 设置第1个upvalue

lua_upvalueindex

  • API 名称: int lua_upvalueindex (int n)
  • 作用描述: 返回第n个upvalue在栈上的虚拟索引。
  • 典型用法示例:
1
2
3
4
5
6
7
static int closure_func(lua_State *L) {
lua_getfield(L, lua_upvalueindex(1), "value"); // 访问upvalue表
return 1;
}

lua_getfield(L, LUA_GLOBALSINDEX, "config");
lua_pushcclosure(L, closure_func, 1); // 创建闭包,1个upvalue

5. 加载与执行Lua代码

luaL_dofile

  • API 名称: int luaL_dofile (lua_State *L, const char *filename)
  • 作用描述: 加载并执行指定的Lua文件。
  • 典型用法示例:
1
2
3
4
if (luaL_dofile(L, "script.lua") != 0) {
printf("执行错误: %s\n", lua_tostring(L, -1));
lua_pop(L, 1);
}

luaL_dostring

  • API 名称: int luaL_dostring (lua_State *L, const char *str)
  • 作用描述: 加载并执行Lua代码字符串。
  • 典型用法示例:
1
2
3
4
5
const char* code = "print('Hello from string')";
if (luaL_dostring(L, code) != 0) {
printf("执行错误: %s\n", lua_tostring(L, -1));
lua_pop(L, 1);
}

luaL_loadfile

  • API 名称: int luaL_loadfile (lua_State *L, const char *filename)
  • 作用描述: 编译Lua文件,但不执行。
  • 典型用法示例:
1
2
3
4
if (luaL_loadfile(L, "module.lua") == 0) {
// 编译成功,可以稍后调用lua_pcall执行
lua_pcall(L, 0, 0, 0);
}

luaL_loadstring

  • API 名称: int luaL_loadstring (lua_State *L, const char *s)
  • 作用描述: 编译Lua代码字符串,但不执行。
  • 典型用法示例:
1
2
3
4
5
6
7
8
const char* code = "local x = 10; return x * 2";
if (luaL_loadstring(L, code) == 0) {
// 编译成功
lua_pcall(L, 0, 1, 0); // 执行,返回一个值
int result = lua_tointeger(L, -1);
printf("结果: %d\n", result);
lua_pop(L, 1);
}

luaL_loadbuffer

  • API 名称: int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz, const char *name)
  • 作用描述: 从缓冲区加载Lua代码。
  • 典型用法示例:
1
2
3
4
5
const char* buffer = "print('loaded from buffer')";
size_t size = strlen(buffer);
if (luaL_loadbuffer(L, buffer, size, "buffer") == 0) {
lua_pcall(L, 0, 0, 0);
}

6. 错误处理

lua_error

  • API 名称: int lua_error (lua_State *L)
  • 作用描述: 抛出Lua错误,等同于return lua_error(L)。
  • 典型用法示例:
1
2
3
4
5
6
7
8
9
10
static int divide(lua_State *L) {
double a = lua_tonumber(L, 1);
double b = lua_tonumber(L, 2);
if (b == 0) {
lua_pushstring(L, "除零错误");
lua_error(L); // 抛出错误
}
lua_pushnumber(L, a / b);
return 1;
}

luaL_error

  • API 名称: int luaL_error (lua_State *L, const char *fmt, ...)
  • 作用描述: 格式化并抛出错误。
  • 典型用法示例:
1
2
3
4
5
6
7
static int my_func(lua_State *L) {
if (!lua_isstring(L, 1)) {
luaL_error(L, "期望字符串参数,实际得到 %s",
luaL_typename(L, 1));
}
return 0;
}

lua_atpanic

  • API 名称: lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf)
  • 作用描述: 设置panic函数,在Lua发生不可恢复错误时被调用。
  • 典型用法示例:
1
2
3
4
5
6
static int panic_handler(lua_State *L) {
printf("Lua panic: %s\n", lua_tostring(L, -1));
return 0; // 退出
}

lua_atpanic(L, panic_handler);

lua_yield

  • API 名称: int lua_yield (lua_State *L, int nresults)
  • 作用描述: 挂起协程执行。
  • 典型用法示例:
1
2
3
4
static int yield_func(lua_State *L) {
lua_pushstring(L, "协程被挂起");
return lua_yield(L, 1); // 挂起,返回一个值
}

7. 内存管理

lua_gc

  • API 名称: int lua_gc (lua_State *L, int what, int data)
  • 作用描述: 控制垃圾回收器(LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOUNT等)。
  • 典型用法示例:
1
2
3
lua_gc(L, LUA_GCCOUNT, 0); // 获取内存使用量(KB)
lua_gc(L, LUA_GCSTEP, 0); // 执行一步垃圾回收
lua_gc(L, LUA_GCRESTART, 0); // 重启垃圾回收器

lua_close

  • API 名称: void lua_close (lua_State *L)
  • 作用描述: 关闭Lua状态机,释放所有内存。
  • 典型用法示例:
1
lua_close(L); // 程序结束前关闭Lua状态机

8. 辅助函数( luaL_* 系列)

luaL_newstate

  • API 名称: lua_State * luaL_newstate (void)
  • 作用描述: 创建新的Lua状态机,加载标准库。
  • 典型用法示例:
1
2
lua_State *L = luaL_newstate(); // 创建新的Lua状态机
luaL_openlibs(L); // 打开标准库

luaL_openlibs

  • API 名称: void luaL_openlibs (lua_State *L)
  • 作用描述: 加载所有Lua标准库。
  • 典型用法示例:
1
2
lua_State *L = luaL_newstate();
luaL_openlibs(L); // 加载所有标准库

luaL_getmetatable

  • API 名称: void * luaL_getmetatable (lua_State *L, const char *tname)
  • 作用描述: 获取注册表中名为tname的元表。
  • 典型用法示例:
1
2
3
4
5
luaL_getmetatable(L, "MyClass");
if (lua_isnil(L, -1)) {
// 元表不存在
lua_pop(L, 1);
}

luaL_check*

  • API 名称: lua_Number luaL_checknumber (lua_State *L, int n), lua_Integer luaL_checkinteger (lua_State *L, int n), const char * luaL_checklstring (lua_State *L, int n, size_t *l), int luaL_checkboolean (lua_State *L, int n)
  • 作用描述: 检查并获取指定位置的参数,类型不匹配时抛出错误。
  • 典型用法示例:
1
2
3
4
5
6
static int my_func(lua_State *L) {
const char* str = luaL_checklstring(L, 1, NULL); // 检查参数1为字符串
int num = luaL_checkinteger(L, 2); // 检查参数2为整数
luaL_checktype(L, 3, LUA_TTABLE); // 检查参数3为表
return 0;
}

luaL_opt*

  • API 名称: lua_Number luaL_optnumber (lua_State *L, int n, lua_Number d), lua_Integer luaL_optinteger (lua_State *L, int n, lua_Integer d), const char * luaL_optlstring (lua_State *L, int n, const char *d, size_t *l)
  • 作用描述: 获取可选参数,如果未提供则返回默认值。
  • 典型用法示例:
1
2
3
4
5
static int my_func(lua_State *L) {
const char* name = luaL_optlstring(L, 1, "默认名称", NULL);
int timeout = luaL_optinteger(L, 2, 30);
return 0;
}

luaL_ref

  • API 名称: int luaL_ref (lua_State *L, int t)
  • 作用描述: 创建对栈顶对象的引用,并将其压入注册表,返回引用ID。
  • 典型用法示例:
1
2
int ref = luaL_ref(L, LUA_REGISTRYINDEX); // 创建对栈顶对象的引用
// 使用时通过lua_rawgeti(L, LUA_REGISTRYINDEX, ref)获取

luaL_unref

  • API 名称: void luaL_unref (lua_State *L, int t, int ref)
  • 作用描述: 释放引用。
  • 典型用法示例:
1
luaL_unref(L, LUA_REGISTRYINDEX, ref); // 释放引用

总结

这些API构成了Lua C API的核心部分,涵盖了与Lua虚拟机交互所需的所有基本操作。通过这些函数,C程序可以灵活地与Lua脚本进行数据交换、函数调用和状态管理。

主要功能领域包括:

  • 栈操作:栈是Lua C API的核心,所有数据交换都通过栈进行
  • 类型系统:提供了完整的类型检查和转换机制
  • 表和全局变量:支持复杂数据结构的操作
  • 函数调用:实现C和Lua之间的无缝调用
  • 错误处理:确保程序稳定性和调试便利性
  • 内存管理:提供垃圾回收控制机制

通过熟练掌握这些API,开发者可以构建功能强大的Lua-C集成应用。