目录
- 一、在C环境中执行Lua脚本
- 二、创建Lua可调用的C库
- 三、C与Lua的数据交互
一、在C环境中执行Lua脚本
在C环境中运行Lua脚本首先需要初始化Lua状态,并加载标准库。示例如下:
lua_State *L; L = luaL_newstate(); // 创建新的Lua状态 if (L == NULL) { DBG_ERROR("无法创建Lua状态: 内存不足\n"); return; } luaL_openlibs(L); // 打开Lua标准库 luaopen_base(L); delay_ms(3000); luaL_dostring(L, lua_code); // 执行Lua代码 while(1) delay_ms(10000); lua_close(L); // 关闭Lua状态
二、创建Lua可调用的C库
为了使Lua能够调用C编写的函数,需要创建相应的C库并注册到Lua环境中。
2.1 linit.c
在linit.c文件中添加自定义模块,如RTC模块:
static const luaL_Reg loadedlibs[] = { {"_G", luaopen_base}, {LUA_COLIBNAME, luaopen_coroutine}, {LUA_TABLIBNAME, luaopen_table}, {LUA_IOLIBNAME, luaopen_io}, {LUA_RTCLIBNAME, luaopen_rtc}, {LUA_STRLIBNAME, luaopen_string}, {LUA_MATHLIBNAME, luaopen_math}, {LUA_UTF8LIBNAME, luaopen_utf8}, #ifdef LUA_COMPAT_BITLIB {LUA_BITLIBNAME, luaopen_bit32}, #endif {NULL, NULL} };
2.2 lualib.h
在lualib.h中定义RTC库的名称及入口函数:
#define LUA_RTCLIBNAME "rtc" LUAMOD_API int (luaopen_rtc)(lua_State *L);
2.3 新建lrtclib.c
创建新的C文件lrtclib.c,实现RTC相关的功能:
#define lrtclib_c #define LUA_LIB #include "lprefix.h" #include "delay.h" #include #include "stm32f1xx_hal.h" #include "rtc.h" #include "lua.h" #include "lauxlib.h" #include "lualib.h" static int luaB_read(lua_State *L) { lua_pushinteger(L, calendar.timecount); lua_pushinteger(L, calendar.w_year); lua_pushinteger(L, calendar.w_month); lua_pushinteger(L, calendar.w_date); lua_pushinteger(L, calendar.hour); lua_pushinteger(L, calendar.min); lua_pushinteger(L, calendar.sec); return 7; } static int luaB_write(lua_State *L) { uint32_t timecout; if (!lua_isinteger(L, 1)) { lua_pushboolean(L, 0); return 1; } timecout = lua_tointeger(L, 1); RTC_Set4Stamp(timecout); lua_pushboolean(L, 1); return 1; } static const luaL_Reg rtc_funcs[] = { {"read", luaB_read}, {"write", luaB_write}, {NULL, NULL} }; LUAMOD_API int luaopen_rtc(lua_State *L) { luaL_newlib(L, rtc_funcs); return 1; }
三、C与Lua的数据交互
C与Lua之间的数据交互主要通过Lua栈来完成,包括参数传递和结果返回。
3.1 参数检查
在C函数中可以通过Lua API检查Lua传递的参数类型:
lua_isinteger(L, 1); // 检查第1个参数是否为整数 lua_isnumber(L, 2); // 检查第2个参数是否为浮点数 lua_isboolean(L, 3); // 检查第3个参数是否为布尔值 lua_isstring(L, 4); // 检查第4个参数是否为字符串 lua_istable(L, 5); // 检查第5个参数是否为表 lua_isfunction(L, 6); // 检查第6个参数是否为函数
3.2 获取参数
从Lua栈中获取参数并转换为C中的基本类型:
lua_tointeger(L, 1); // 获取第1个参数,转换为整数 lua_tonumber(L, 2); // 获取第2个参数,转换为浮点数 lua_toboolean(L, 3); // 获取第3个参数,转换为布尔值 lua_tostring(L, 4); // 获取第4个参数,转换为字符串
3.3 返回结果
C函数可以向Lua返回多个结果,通过将结果压入Lua栈来实现:
lua_pushinteger(L, 1); lua_pushnumber(L, 2.2); lua_pushboolean(L, 0); lua_pushstring(L, "a"); return 4; // 返回4个结果
3.4 获取表(数组)
从Lua栈中获取表(数组)并处理:
static int luaB_send(lua_State *L) { uint16_t number, len, i; uint8_t data[1024]; if (!lua_isinteger(L, 1)) return 0; if (!lua_isinteger(L, 2)) return 0; if (!lua_istable(L, 3)) return 0; number = lua_tointeger(L, 1); if (number > 6) { lua_pushboolean(L, 0); return 1; } len = lua_tointeger(L, 2); for (i = 0; i
3.5 返回数组
从C函数返回数组给Lua:
static int luaB_receive(lua_State *L) { uint16_t number, len, i; uint8_t data[1024]; if (!lua_isinteger(L, 1)) return 0; number = lua_tointeger(L, 1); if (number > 6) { lua_pushboolean(L, 0); return 1; } RS_Receive_Data(number, data, &len); lua_pushinteger(L, len); lua_newtable(L); // 创建新表 lua_pushnumber(L, -1); lua_rawseti(L, -2, 0); for (i = 0; i
3.6 调用Lua函数
在C中调用Lua函数:
lua_getglobal(L, "函数名"); lua_call(L, 0, 0);
如果觉得有用,请点赞、收藏并关注!