玩转Luat OS篇①——C与Lua混合编程

17 篇文章 50 订阅 ¥19.90 ¥99.00
本文介绍了如何在C环境中运行Lua脚本,并详细阐述了封装C语言库以便被Lua调用的过程,包括创建linit.c、lualib.h和lrtclib.c文件。接着,讨论了C和Lua的交互,讲解了如何判断传入参数、获取和返回结果、处理table数组以及调用Lua函数等关键步骤。
摘要由CSDN通过智能技术生成

一、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);   

觉得好,就一键三连呗(点赞+收藏+关注)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小康师兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值