目录
- 参考
- 简介
- C函数返回值
- C函数检查并读取虚拟栈内数据
- [check + 默认值](#check + 默认值)
- C函数判断虚拟栈内数据类型
- C函数栈数据类型转换
- C函数推入数据
参考
接上文https://blog.csdn.net/qq_42039294/article/details/139806522
本文内容主要参考https://www.bilibili.com/video/BV1UR4y1P7Nd/
简介
为了方便测试,本文把LUA部署在电脑上,在电脑上测试而不是上文单片机中测试。操作流程没有区别
lua向C传递的参数由填写在lua函数中的形参给定,这些形参首先会进入lua虚拟栈中,虚拟栈句柄指针再传递到C函数中,由C函数做弹出参数或者压入参数的操作
C函数的返回值指定LUA函数返回参数数量。LUA函数返回参数也来自于虚拟栈
以my_lua_add(a, b)函数为例,该功能用于再lua中实现a+b,然后将结果返回,处理流程如下:

C函数返回值
C函数返回值

C函数检查并读取虚拟栈内数据
表中arg位置就是栈索引idx,为了匹配lua中文手册,描述为arg
| 函数名 | 作用 |
|---|---|
| luaL_checkany | 检查arg位置是否有参数,包括nil,如果没有的触发错误 |
| luaL_checkinteger | 检查arg位置是否为整形数字或者可以转换为整型数字,如果没有的触发错误 "转换"的例子:33, "33", 33.0, 不可"转换"的例子:"a", 33.2 |
| luaL_checknumber | 浮点型数字或者可转换为浮点型数字 |
| luaL_checkstring | 字符串类型或者可转换为字符串类型,如果匹配,返回字符串指针,如果不匹配抛出错误 |
| luaL_checklstring | 字符串类型或者可转换为字符串类型,如果匹配,那么将字符串长度传入形参中,返回字符串指针,如果不匹配抛出错误 |
| luaL_checktype | 检查类型是否匹配形参t |
| luaL_checkoption | 似乎用来做命令行选项的,C维护一个选项-递增枚举值表格,传入之后,当lua指令带形参的时候,返回枚举值 |
| luaL_checkstack | 扩展栈空间 |
| ... |
check type枚举值
c
#define LUA_TNONE (-1)
#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TLIGHTUSERDATA 2
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8
测试
c
#include "stdio.h"
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static int function_pp (lua_State *L) {
printf("1 arg is %f\r\n", luaL_checknumber(L, 1));
printf("2 arg is %I64d\r\n", luaL_checkinteger(L, 2));
printf("3 arg is %s\r\n", luaL_checkstring(L, 3));
return 0;
}
static const luaL_Reg extlib[] = {
{"pp", function_pp},
{NULL, NULL}
};
int luaopen_ext (lua_State *L) {
luaL_newlib(L, extlib);
return 1;
}
PS C:\Users\Administrator\Desktop\lua> mingw32-make.exe
========== Running app.exe ==========
./app.exe
Lua 5.4.8 Copyright (C) 1994-2025 Lua.org, PUC-Rio
> ext.pp(33.5, 666, "ddml")
1 arg is 33.500000
2 arg is 666
3 arg is ddml
check + 默认值
| 函数名 | 作用 |
|---|---|
| luaL_optinteger | 如果arg是一个整数或者可以转换为一个整数,返回该整数。 若该参数不存在或是 nil, 返回形参d。 除此之外的情况,抛出错误 |
| luaL_optlstring | |
| luaL_optnumber | |
| luaL_optstring |
测试
c
static int function_pp (lua_State *L) {
int cnum = luaL_optinteger(L, 1, 8848);
printf("cnum = %d\n", cnum);
return 0;
}
PS C:\Users\winston\Desktop\TEST\lua> .\app.exe
Lua 5.4.8 Copyright (C) 1994-2025 Lua.org, PUC-Rio
> ext.pp()
cnum = 8848
> ext.pp(1)
cnum = 1
> ext.pp(nil)
cnum = 8848
> ext.pp("string")
stdin:1: bad argument #1 to 'pp' (number expected, got string)
stack traceback:
[C]: in function 'ext.pp'
stdin:1: in main chunk
[C]: in ?
C函数判断虚拟栈内数据类型
| 函数名 | 作用 |
|---|---|
| lua_isboolean | |
| lua_iscfunction | |
| lua_isfunction | |
| lua_isinteger | |
| lua_islightuserdata | |
| lua_isnil | |
| lua_isnone | |
| lua_isnoneornil | |
| lua_isnumber | |
| lua_isstring | |
| lua_istable | |
| lua_isthread | |
| lua_isuserdata | |
| lua_isyieldable |
测试
c
static int function_pp (lua_State *L) {
printf("%s\n",lua_isinteger(L, 1) ?"is int":"not int");
return 0;
}
PS C:\Users\winston\Desktop\TEST\lua> .\app.exe
Lua 5.4.8 Copyright (C) 1994-2025 Lua.org, PUC-Rio
> ext.pp(1)
is int
> ext.pp(1.0)
not int
> ext.pp("string")
not int
> ext.pp()
not int
C函数栈数据类型转换
| 函数名 | 作用 |
|---|---|
| lua_toboolean | false,nil, 空值是假的,其余是真 |
| lua_tocfunction | |
| lua_tointeger | |
| lua_tointegerx | 相比于lua_tointeger,多一个指针用来传递是否转换成功 |
| lua_tostring | |
| lua_tolstring | |
| lua_tonumber | |
| lua_tonumberx | |
| lua_topointer | |
| lua_tothread | |
| lua_touserdata |
测试代码
c
static int function_pp (lua_State *L) {
printf("%s", lua_toboolean(L, 1) ? "TRUE\n" : "FALSE\n");
return 0;
}
PS C:\Users\winston\Desktop\TEST\lua> .\app.exe
Lua 5.4.8 Copyright (C) 1994-2025 Lua.org, PUC-Rio
TRUE
TRUE
> ext.pp(true) ext.pp(false)
TRUE
FALSE
> ext.pp(nil) ext.pp()
FALSE
FALSE
C函数推入数据
| 函数名 | 作用 |
|---|---|
| lua_pushboolean | 推入bool型 |
| lua_pushnil | 推入nil |
| lua_pushnumber | 推入浮点形 |
| lua_pushinteger | 推入整形 |
| lua_pushfstring | 推入格式化字符串, (相比于snprintf功能不完善,不建议使用) |
| lua_pushliteral | 推入字符串,字符串必须是字面量 |
| lua_pushlstring | 推入字符串,带长度 |
| lua_pushstring | 推入字符串 |
| lua_pushvfstring | 等同于pushfstring,但是使用valist接收参数 |
| lua_pushvalue | 栈中某个索引的栈值复制一份,放到栈顶 |
测试
c
static int function_pp (lua_State *L) {
lua_pushnil(L);
lua_pushboolean(L, 1);
lua_pushnumber(L, 666.88);
lua_pushinteger(L, 342);
lua_pushstring(L, "pp");
lua_pushvalue(L, 1);
return 6;
}
PS C:\Users\winston\Desktop\TEST\lua> .\app.exe
Lua 5.4.8 Copyright (C) 1994-2025 Lua.org, PUC-Rio
> ext.pp()
nil true 666.88 342 pp nil