目录
一、C环境中运行Lua脚本
lua_State *L;
L = luaL_newstate(); //建立Lua运行环境
if (L == NULL) {
DBG_ERROR("lua cannot create state: not enough memory\n");
return ;
}
luaL_openlibs(L);
luaopen_base(L);
delay_ms(3000);
luaL_dostring(L, lua_code); //运行Lua脚本
while(1)
delay_ms(10000);
lua_close(L);
二、封装可被Lua调用的C语言库
2.1 linit.c
增加自定义模块rtc
static const luaL_Reg loadedlibs[] = {
{"_G", luaopen_base},
// {LUA_LOADLIBNAME, luaopen_package},
{LUA_COLIBNAME, luaopen_coroutine},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_RTCLIBNAME, luaopen_rtc},
// {LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_UTF8LIBNAME, luaopen_utf8},
// {LUA_DBLIBNAME, luaopen_debug},
#if defined(LUA_COMPAT_BITLIB)
{LUA_BITLIBNAME, luaopen_bit32},
#endif
{NULL, NULL}
};
2.2 lualib.h
#define LUA_RTCLIBNAME "rtc"
LUAMOD_API int (luaopen_rtc) (lua_State *L);
2.3 新建lrtclib.c
/*
** $Id: lcorolib.c,v 1.10 2016/04/11 19:19:55 roberto Exp $
** Coroutine Library
** See Copyright Notice in lua.h
*/
#define lrtclib_c
#define LUA_LIB
#include "lprefix.h"
#include "delay.h"
#include <stdlib.h>
#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和Luc交互
Lua的栈,通过出栈入栈,获取参数,返回结果
3.1 判断是否传入参数
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_tointeger(L,1); //获取第1个参数,转换成整数
lua_tonumber(L,2); //获取第2个参数,转换成浮点
lua_toboolean(L,3); //获取第3个参数,转换成布尔
lua_tostring(L,4); //获取第4个参数,转换成字符串
3.3 返回结果
lua函数可以返回多个结果
lua_pushinteger(L,1);
lua_pushnumber(L,2.2);
lua_pushboolean(L,0);
lua_pushstring(L,"a");
return 4;//函数返回结果的个数
3.4 获取table数组
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<len;i++)
{
lua_rawgeti(L,3,i+1);
data[i]= lua_tonumber(L,-1);//获取数组
lua_pop(L,1);
}
RS_Send_Data(number,data,len,3000);
lua_pushboolean(L,1);
return 1;
}
3.5 返回数组
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返回table类型,先new一个,再压入栈顶
lua_pushnumber(L,-1); //确定数组首地址
lua_rawseti(L,-2,0); //
for(i=0;i<len;i++)
{
lua_pushinteger(L,data[i]);
lua_rawseti(L, -2, i+1);
}
return 2;
}
3.6 调用Lua函数
lua_getglobal(L, "函数名");
lua_call(L,0,0);
觉得好,就一键三连呗(点赞+收藏+关注)