Lua移植到标准ANSI C环境

本文目录

  • 1、引言
  • 2、环境准备
    • 2.1 源码下载
    • 2.2 项目构建环境准备
  • 3、项目编译
    • 3.1 添加main.c
    • 3.2 Kconfig选择模块
    • 3.3 项目构建
    • 3.4 项目编译
  • 4、运行


文章对应视频教程:

在下方喔 ~~~ 欢迎关注


点击图片或链接访问我的B站主页~~~

lau解释器移植与功能验证


1、引言

本文将介绍如何将Lua解释器移植到标准的ANSI C环境。
实现ANSI C的移植,就可以实现在嵌入式各类板卡的移植。
当然,你的板卡得具备ANSI C环境,一般情况keil、GCC都会有C库实现。
关于Lua解释器的重要性,或者有何特殊指出,可以看看我得上篇文章:
《可用于嵌入式的解释器调研对比,及lua解释器介绍》


2、环境准备

2.1 源码下载

您可以在Lua官方网站上下载Lua解释器的源代码。以下是Lua官方网站的链接:

Lua解释器下载

在该网页上,点击的Lua解释器源代码的下载链接(图中红色框部分),进行源代码下载,可能有点慢。

在这里插入图片描述
下载完成后,进行接下,得到下图的文件,提取其中的src文件夹,将src中的makefilelua.cluac.c文件删除,待用。
在这里插入图片描述

2.2 项目构建环境准备

参考往期博客《Cmake+Kconfig项目构建》,搭建一个空的项目框架,用来测试Lua是否移植成功。

复制项目构建模板,修改名字,修改CMakeLists.txt和kconfig文件,方便后续模块化移植到自己的项目中,目录结构如下。

在这里插入图片描述
这里也可以直接复制到keil工程中,只要你的环境具有ANSI C接口即可。

将前面准备好的源码复制到source/lua文件夹下,注意是将src中的makefilelua.cluac.c文件删除后,剩下的代码。


3、项目编译

3.1 添加main.c

我们需要在main.c中实现对lua代码的解释功能。
由于我在window环境下,我可以很轻松的打开文件,所以直接采用的文件读取的方式执行。
大家也可以直接将代码写在内存中,类似与下面这种方式:

char buff[] = "printf(123)";

我这边的代码比较复杂,还是用读取文件实现。

main.c内容如下:

#include "stdio.h"
#include <stdlib.h>

#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "string.h"

#define BUFFER_SIZE 1024*1024*1

static lua_State *L = NULL ;

int lua_deal_line(const char *str)
{
	int ret = luaL_dostring(L,str);
	if(ret != LUA_OK)
	{
		printf("%s\r\n",lua_tostring(L ,-1));
		return -1;
	}	
	return 0;
}


int main(void)
{
	L = luaL_newstate();
	luaL_openlibs(L);

    FILE *file;
    char buffer[BUFFER_SIZE] = {0};
    size_t read_size;

    // 打开文件
    file = fopen("test.lua", "rb"); // 使用"rb"模式以二进制方式读取文件
    if (file == NULL) {
        perror("无法打开文件");
        return 1;
    }

    // 读取文件内容到缓冲区
    read_size = fread(buffer, 1, BUFFER_SIZE - 1, file); // 保留一个字节给'\0'
    if (read_size == 0 && ferror(file)) {
        perror("read file error\r\n");
        fclose(file);
        return 1;
    }

    // 添加字符串末尾的空字符
    buffer[read_size] = '\0';

    // 关闭文件
    fclose(file);


    lua_deal_line(buffer);

    lua_close(L);
    return 1;
}

创建test.lua文件放在当前路径下。

-- Lua 基本语法
print("Running basic syntax test...")
assert(true)  -- 如果代码运行到这里,没有错误发生,那么基本语法测试通过

-- Lua 数据类型
print("Running data type test...")
local num = 10          -- number
local str = "Hello"     -- string
local bool = true       -- boolean
local tbl = {1, 2, 3}   -- table
local func = function() return "I am a function" end  -- function
assert(type(num) == "number")
assert(type(str) == "string")
assert(type(bool) == "boolean")
assert(type(tbl) == "table")
assert(type(func) == "function")

-- Lua 变量
print("Running variable test...")
local localVar = "I am local"
_G.globalVar = "I am global"
assert(localVar == "I am local")
assert(_G.globalVar == "I am global")

-- Lua 循环
print("Running loop test...")
local sum = 0
for i = 1, 5 do
    sum = sum + i
end
assert(sum == 15)

sum = 0
local i = 1
while i <= 5 do
    sum = sum + i
    i = i + 1
end
assert(sum == 15)

-- Lua 流程控制
print("Running control flow test...")
local x = 10
local result
if x > 5 then
    result = "greater"
elseif x == 5 then
    result = "equal"
else
    result = "less"
end
assert(result == "greater")

-- Lua 函数
print("Running function test...")
function add(a, b)
    return a + b
end
assert(add(5, 3) == 8)

-- Lua 运算符
print("Running operator test...")
local a, b = 10, 20
assert(a + b == 30)
assert(a - b == -10)
assert(a * b == 200)
assert(a / b == 0.5)
assert(a % b == 10)
assert(a ^ 2 == 100)

-- Lua 字符串
print("Running string test...")
local s = "Lua"
assert(#s == 3)
assert(s .. " programming" == "Lua programming")

-- Lua 数组
print("Running array test...")
local arr = {10, 20, 30, 40, 50}
assert(arr[1] == 10)
assert(#arr == 5)

-- Lua 迭代器
print("Running iterator test...")
local function squareIterator(max, current)
    current = current + 1
    if current <= max then
        return current, current * current
    end
end
local results = {}
for i, n in squareIterator, 5, 0 do
    table.insert(results, n)
end
assert(#results == 5)
assert(results[1] == 1)
assert(results[5] == 25)

-- Lua table(表)
print("Running table test...")
local person = {name = "John", age = 30}
assert(person.name == "John")
assert(person.age == 30)

-- Lua 模块与包
print("Running module test...")
-- 假设有一个 module_name.lua 文件,内容如下:
-- local M = {}
-- function M.hello() return "Hello, module!" end
-- return M
-- local module = require("module_name")
-- assert(module.hello() == "Hello, module!")

-- Lua 元表(Metatable)
print("Running metatable test...")
local mt = {
    __add = function(table1, table2)
        local sum = {}
        for k, v in pairs(table1) do
            sum[k] = v + table2[k]
        end
        return sum
    end
}
local t1 = {1, 2, 3}
local t2 = {4, 5, 6}
setmetatable(t1, mt)
local t3 = t1 + t2
assert(t3[1] == 5)
assert(t3[2] == 7)
assert(t3[3] == 9)

-- Lua 协同程序(coroutine)
-- print("Running coroutine test...")
-- local co = coroutine.create(function()
--     for i = 1, 5 do
--         coroutine.yield(i)
--     end
-- end)
-- local _, first = coroutine.resume(co)
-- assert(first == 1)
-- local _, second = coroutine.resume(co)
-- assert(second == 2)

-- Lua 文件 I/O
-- print("Running file I/O test...")
-- local file = io.open("test.txt", "w")
-- file:write("Hello, file!")
-- file:close()
-- file = io.open("test.txt", "r")
-- local content = file:read("*all")
-- file:close()
-- assert(content == "Hello, file!")

-- Lua 错误处理
print("Running error handling test...")
local status, err = pcall(function()
    error("An error occurred")
end)
assert(not status)
assert(string.find(err, "An error occurred"))

-- Lua 调试(Debug)
-- print("Running debug test...")
-- local debug = require("debug")
-- local traceback
-- local function myfunc()
--     traceback = debug.traceback("Stack trace")
-- end
-- myfunc()
-- assert(string.find(traceback, "Stack trace"))

-- Lua 垃圾回收
print("Running garbage collection test...")
local tbl = {1, 2, 3}
setmetatable(tbl, {__gc = function() print("Garbage collected") end})
tbl = nil
collectgarbage()  -- 在控制台中应能看到 "Garbage collected"

-- Lua 面向对象
print("Running object-oriented test...")
local Animal = {name = "", age = 0}
function Animal:new(o, name, age)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    self.name = name or ""
    self.age = age or 0
    return o
end
function Animal:speak()
    return "I am " .. self.name .. ", " .. self.age .. " years old."
end

local dog = Animal:new(nil, "Dog", 5)
assert(dog:speak() == "I am Dog, 5 years old.")

print("All tests passed!")


3.2 Kconfig选择模块

project\pro1目录下,打开powershell,输入python .\ck_script.py cn进入到图形配置界面。

在这里插入图片描述

确保回车选中该模块,再按Q Y按键退出。


3.3 项目构建

在powershell,输入python .\ck_script.py b进行项目构建,构建完成后,对文件的编译规则就已经生成。
在这里插入图片描述


3.4 项目编译

在powershell,输入python .\ck_script.py m进行项目编译,结果如下。

在这里插入图片描述


4、运行

在powershell,输入.\lua.exe运行程序,结果如下。
在这里插入图片描述
这个Lua脚本验证了我们需要的基本语法、数据类型、变量、循环、流程控制、函数、运算符、字符串、数组、迭代器、table(表)、元表(Metatable)、错误处理、垃圾回收、面向对象等功能。


时间流逝、年龄增长,是自己的磨炼、对知识技术的应用,还有那不变的一颗对嵌入式热爱的心!

到这里就结束了!希望大家给我的文章和B站视频
点赞o( ̄▽ ̄)d、关注(o)/~、评论(▽)!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/692418.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ-工作模式(Publish模式Routing模式)

文章目录 发布/订阅&#xff08;Publish/Subscribe&#xff09;交换机临时队列绑定总体代码示例 路由&#xff08;Routing&#xff09;绑定直连交换机多重绑定发送日志订阅总体代码示例 更多相关内容可查看 发布/订阅&#xff08;Publish/Subscribe&#xff09; 构建一个简单的…

达梦8 探寻达梦排序原理:新排序机制(SORT_FLAG=1)

测试版本&#xff1a;--03134283938-20221019-172201-20018 达梦的排序机制由四个dm.ini参数控制&#xff1a; #maximum sort buffer size in Megabytes &#xff0c;有效值范围&#xff08;1~2048&#xff09; SORT_BUF_SIZE 100 #ma…

FinalShell导出服务器配置信息密码password是加密的,如何解密?

本章教程,主要实现了一个小的功能,对FinalShell导出的配置信息,进行解密。 FinalShell导出之后,会产生一个json文件,例如下面这种json格式,里面记录了服务器的IP地址,端口和密码,里面的密码是经过加密处理的,本文主要利用java代码实现对这个password进行解密还原。 {&…

【设计模式】行为型设计模式之 策略模式学习实践

介绍 策略模式&#xff08;Strategy&#xff09;&#xff0c;就是⼀个问题有多种解决⽅案&#xff0c;选择其中的⼀种使⽤&#xff0c;这种情况下我们 使⽤策略模式来实现灵活地选择&#xff0c;也能够⽅便地增加新的解决⽅案。⽐如做数学题&#xff0c;⼀个问题的 解法可能有…

五、身份与访问管理—身份管理和访问控制管理(CISSP)

目录 1.身份管理 1.1 目录技术 1.2 单点登录 1.2.1 Kerberos认证 1.2.2 SESAME认证 1.2.3 KryptoKnight认证 1.3 联合身份管理 1.3.1 SAML安全断言标记语言 1.3.2 标记语言 1.3.3 OpenID 1.3.4 OAuth 1.3.5 OIDC(OpenID Connect) 2.身份即服务(IDaaS) 2.1 AA…

如何提高网站收录?

GSI服务就是专门干这个的&#xff0c;这个服务用的是光算科技自己研发的GPC爬虫池系统。这个系统通过建立一个庞大的站群和复杂的链接结构&#xff0c;来吸引谷歌的爬虫。这样一来&#xff0c;你的网站就能更频繁地被谷歌的爬虫访问&#xff0c;从而提高被收录的机会。 说到效…

【漏洞复现】Apache OFBiz 路径遍历导致RCE漏洞(CVE-2024-36104)

0x01 产品简介 Apache OFBiz是一个电子商务平台&#xff0c;用于构建大中型企业级、跨平台、跨数据库、跨应用服务器的多层、分布式电子商务类应用系统。是美国阿帕奇(Apache)基金会的一套企业资源计划(ERP)系统。该系统提供了一整套基于Java的Web应用程序组件和工具。 0x02 …

【Nacos 2.3.3支持Postgre SQL数据源配置】

Nacos 2.3.3支持Postgre SQL数据源配置 1、Nacos下载2、 插件下载&#xff1a;3、SQL脚本获取、nacos数据库创建、插件编译4、Nacos 集群搭建方式&#xff1a; 1、Nacos下载 下载地址&#xff1a; https://download.nacos.io/nacos-server/nacos-server-2.3.2.zip 或者自行在官…

OrangePi AIpro Ubuntu 22.04 aarch64 安装MySql 8.0

查看MySQL安装包 接下来可以使用以下命令安装MySQL服务器&#xff1a; 安装MySQL 8.0 # 安装最新版本 sudo apt install -y mysql-server # 安装指定版本 sudo apt install -y mysql-server-8.0初始化配置信息 sudo mysql_secure_installationVALIDATE PASSWORD COMPONENT ca…

pc之间的相互通信详解

如图&#xff0c;实现两台pc之间的相互通信 1.pc1和pc2之间如何进行通讯。 2.pc有mac和ip&#xff0c;首先pc1需要向sw1发送广播&#xff0c;sw1查询mac地址表&#xff0c;向router发送广播&#xff0c;router不接受广播&#xff0c;router的每个接口都有ip和mac&#xff0c;…

【Java笔记】第10章:接口

前言1. 接口的概念与定义2. 接口的声明与语法3. 接口的实现4. 接口的继承5. 接口的默认方法6. 接口的静态方法7. 接口的私有方法8. 接口的作用9. 接口与抽象类的区别10. 接口在Java集合中的应用结语 上期回顾:【Java笔记】第9章&#xff1a;三个修饰符 个人主页&#xff1a;C_G…

Java | Leetcode Java题解之第139题单词拆分

题目&#xff1a; 题解&#xff1a; public class Solution {public boolean wordBreak(String s, List<String> wordDict) {Set<String> wordDictSet new HashSet(wordDict);boolean[] dp new boolean[s.length() 1];dp[0] true;for (int i 1; i < s.len…

力扣每日一题85:最大矩形

题目 困难 相关标签 相关企业 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵&#xff0c;找出只包含 1 的最大矩形&#xff0c;并返回其面积。 示例 1&#xff1a; 输入&#xff1a;matrix [["1","0","1","0",&q…

毫米波SDK使用1

本文档是AM273x等毫米波雷达处理器SDK的配置和使用&#xff0c;主要参考TI的官方文档《mmwave mcuplus sdk user guide》。这里仅摘取其中重要的部分&#xff0c;其余枝节可参考原文。 2 系统概览 mmWave SDK分为两个主要组件:mmWave套件和mmWave演示。 2.1. mmWave套件 mmWa…

react 基础样式的控制(行内和className)

import ./index.cssconst style{color:red,font-size:150px }function App() {return (<div className"App"><h1>行内样式控制</h1><h1 style{{color:red,font-size:150px}} >asd </h1><span style{style} >asd </span>&l…

MATLAB算法实战应用案例精讲-【数模应用】数据孤岛(概念篇)

目录 前言 算法原理 什么是数据孤岛 数据孤岛产生的原因 数据孤岛的问题 什么时候数据孤岛不是坏事&#xff1f; 为什么很难摆脱数据孤岛 数据孤岛对企业造成的负面效应 数据孤岛的影响 数据孤岛的危害 如何解决数据孤岛问题 如何摆脱数据孤岛&#xff1f; 前言 数…

Java学习 - Maven - 常用命令(学习精选)

前言 在上一篇文章中&#xff0c;我们对 Maven 有了初步的了解&#xff0c;包括它的定义、安装步骤以及一些基本的配置方法。Maven 是一个强大的项目管理工具&#xff0c;它可以帮助开发者自动化构建过程&#xff0c;并且管理项目的依赖关系。 今天&#xff0c;我们将深入探讨…

高光谱图像聚类的像素-超像素对比学习与伪标签校正

Pixel-Superpixel Contrastive Learning and Pseudo-Label Correction for Hyperspectral Image Clustering 文章目录 Pixel-Superpixel Contrastive Learning and Pseudo-Label Correction for Hyperspectral Image Clustering摘要引言相关方法对比学习 方法超像素对比学习像素…

攻防世界---misc---Excaliflag

1、题目描述&#xff0c;下载附件是一张图片 2、用winhex分析&#xff0c;没有发现奇怪的地方 3、在kali中使用binwalk -e 命令&#xff0c;虽然分离出来了一些东西&#xff0c;但是不是有用的 4、最后用stegsolve分析&#xff0c;切换图片&#xff0c;发现有字符串&#xff0c…

番外篇 | 利用华为2023最新Gold-YOLO中的Gatherand-Distribute对特征融合模块进行改进

前言:Hello大家好,我是小哥谈。论文提出一种改进的信息融合机制Gather-and-Distribute (GD) ,通过全局融合多层特征并将全局信息注入高层,以提高YOLO系列模型的信息融合能力和检测性能。通过引入MAE-style预训练方法,进一步提高模型的准确性。🌈 目录 🚀1.论文解…