Qt、C/C++环境中内嵌LUA脚本、实现LUA函数的调用执行

Qt、C/C++环境中内嵌LUA脚本、实现LUA函数的调用执行

  • Chapter1. Qt、C/C++环境中内嵌LUA脚本、实现LUA函数的调用执行
    • 1、LUA简介
    • 2、LUA脚本的解释器和编译器
    • 3、C环境中内嵌LUA执行LUA函数调用
    • 4、Qt内嵌LUA执行LUA函数调用
    • 5、运行结果
    • 6、内嵌LUA脚本在实际项目中的案例应用


Chapter1. Qt、C/C++环境中内嵌LUA脚本、实现LUA函数的调用执行

参考链接1:https://blog.51cto.com/u_15950551/6031885

参考链接2: https://blog.csdn.net/qq_23345187/article/details/112710677?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-6-112710677-blog-87274903.235%5Ev38%5Epc_relevant_sort_base3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-6-112710677-blog-87274903.235%5Ev38%5Epc_relevant_sort_base3&utm_relevant_index=7

1、LUA简介

LUA是一个脚本语言,由标准C编写而成,几乎在所有操作系统和平台上都可以编译、运行,可以很方便的嵌入到其他C/C++环境中,如Qt、VS2012等。

一般的lua脚本文件的后缀为.lua,移植lua源码异常的简单,下载源码包后,直接编译即可,因为上面我们说过了LUA是用标准C编写的,所以几乎你常见的编程环境它都能编译LUA。

LUA源码下载地址:​ ​http://www.lua.org/ftp/​

下载lua-5.1.5.tar.gz然后解压。
在这里插入图片描述

在这里插入图片描述
将以上这些文件除了lua.c和luac.c加入到你的开发环境中进行编译,就算移植完成了!

lua.c和luac.c中都有main函数,需要分别编译这两个我文件,其中,lua.c编译出来是解析器,luac.c编译出来是编译器。

2、LUA脚本的解释器和编译器

Q:什么是解释器和编译器?

A:

解释器:顾名思义,就是对LUA进行解释说明,能够认识出LUA脚本并运行

编译器:对LUA脚本文件进行编译,生成可以供解释器运行的LUA可执行程序

我使用lua源码包版本在windows下编译出了可执行文件,其中:lua.exe为解释器,luac.exe为编译器。

3、C环境中内嵌LUA执行LUA函数调用

这里我使用的C开发环境是:Eclipse C/C++配合MinGW。

移植很简单的,将lua源码除了lua.c和luac.c之外,其他源码加入到工程即可。

4、Qt内嵌LUA执行LUA函数调用

移植很简单的,将lua源码文件除了lua.c和luac.c之外,加入到Qt工程即可。

我为了方便管理,将lua源码放到了一个目录里,然后放到mainwindow.cpp同文件夹下:
在这里插入图片描述
在这里插入图片描述
然后编译工程即可。

5、运行结果

在这里插入图片描述
在这里插入图片描述
lua文件
test.lua

function sum(x,y)
       return x + y + 61
end

test2.lua

local num=testfuction(10);

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDebug>

#include <stdio.h>

extern "C"
{
#include "lua/lua.h"
#include "lua/lauxlib.h"
#include "lua/lualib.h"
}


lua_State *L;
int countsum(int x,int y)
{
    int sum;
    lua_getglobal(L,"sum");//指向需要调用的lua函数
    //压入参数
    lua_pushnumber(L,x);//压入第一个参数
    lua_pushnumber(L,y);//压入第二个参数
    //调用函数
    lua_pcall(L,2,1,0); //压入两个参数,返回一个结果
    //取得结果
    sum = (int)lua_tonumber(L,-1); //取得栈顶元素
    lua_pop(L,1); //清理栈
    return sum;
}

int  setnum(int num){
    return 100-num;
}

static int testfuction(lua_State* L)
{
    int num = (int)lua_tonumber(L, -1);  //从lua中取得一个数
    lua_pushnumber(L, setnum(num));
    qDebug()<<"fuction start!!!!!\n";
    qDebug()<<"lua input number is"<<num;
    return 1;
}



MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);


}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    L =  luaL_newstate();//新建lua虚拟机
        luaL_openlibs(L);//加载lua的string math等库
        luaL_dofile(L,"test.lua");//绝对路径 执行脚本文件
        int sum = countsum(100,200);
        qDebug()<<"test result is"<<sum;
        lua_close(L); //关闭lua文件

        lua_State* L = lua_open();
        luaopen_base(L);

        // C++的函数和封装函数都必须是静态的,不可以是非静态的
        lua_register(L, "testfuction", testfuction);
        luaL_dofile(L, "test2.lua"); //绝对路径
        lua_close(L);

}

6、内嵌LUA脚本在实际项目中的案例应用

上面已经介绍了LUA脚本及内嵌入C/C++环境,那么实际的使用场景是怎样的呢?

下面就举一个实际的使用案例。

现在有一个嵌入式相关项目,使用Qt做一款上位机软件,通过串口和下位机进行通信,通信协议为modbus,下位机为各类485型传感器。

目前有一个温度传感器需要接入上位机、一个水浸入检测传感器需要接入;

水浸传感器是开关量传感器,只有0和1两种状态;

温度传感器是数字量传感器,厂家为了迎合modbus协议并且为了数据好处理,将浮点格式的温度值扩大了10倍进行传输,例如28.5度扩大10倍是285,将285通过modbus进行传输。

那么现在问题就来了,温度传感器和水浸传感器虽然通信协议是一致的,上位机通过modbus接收到传感器数据后:

如果是温度传感器的,那么需要除以10倍才能得到正确的温度值;

但是如果是水浸传感器就不用除以10倍;

而此时如果还有一个VOC传感器需要接入,并且上位机需要将读取到的VOC数值进行一个复杂的公式转换成THC后在显示;

这时候你就会发现,每一个传感器都有不一样的最终值计算方式,难道要将所有传感器的计算格式方式都包含进上位机中吗?

简单的加减乘除还可以包含进上位机中,如果是VOC转THC这种复杂计算公式的,你怎么包含进去呢?

所以,这就体现了LUA的用处!

办法如下:

在上位机中嵌入LUA,编写一个mylua.lua脚本文件,里面就一个getValue函数。

当上位机接收到传感器数值时,通过LUA提供的API函数,将该数值传入getValue.lua脚本中的getValue函数,然后在获得getValue的返回值,

而在getValue中实现了数值的转换或计算,由于getValue.lua脚本文件是独立于上位机的,可以随便更改函数体,当传感器是水浸时,getValue直接返回输入的值即可,当传感器是温度时,getValue返回输入的值除以10即可;

所以这样就实现了上位机针对不同传感器的数据处理!

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

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

相关文章

手机变电脑2023之虚拟电脑droidvm

手机这么大的内存&#xff0c;装个app来模拟linux&#xff0c;还是没问题的。 app 装好后&#xff0c;手指点几下确定按钮&#xff0c;等几分钟就能把linux桌面环境安装好。 不需要敲指令&#xff0c; 不需要对手机刷机&#xff0c; 不需要特殊权限&#xff0c; 不需要找驱…

opencv-32 图像平滑处理-高斯滤波cv2.GaussianBlur()

在进行均值滤波和方框滤波时&#xff0c;其邻域内每个像素的权重是相等的。在高斯滤波中&#xff0c;会将中心点的权重值加大&#xff0c;远离中心点的权重值减小&#xff0c;在此基础上计算邻域内各个像素值不同权重 的和。 基本原理 在高斯滤波中&#xff0c;卷积核中的值不…

第一篇:一文看懂 Vue.js 3.0 的优化

我们的课程是要解读 Vue.js 框架的源码&#xff0c;所以在进入课程之前我们先来了解一下 Vue.js 框架演进的过程&#xff0c;也就是 Vue.js 3.0 主要做了哪些优化。 Vue.js 从 1.x 到 2.0 版本&#xff0c;最大的升级就是引入了虚拟 DOM 的概念&#xff0c;它为后续做服务端渲…

Scala按天写入日志文件

如果希望把每天出错的信息写入日志文件&#xff0c;每天新建一个文件。 package test.scala import java.io.{File, FileWriter} import java.text.SimpleDateFormat import java.util.{Calendar, Date} import scala.concurrent.ExecutionContext.Implicits.global import sc…

CS录屏教程,录制游戏需要注意哪些方面?

​最近有个CS手游的玩家小伙伴咨询想要做一些游戏视频录制&#xff0c;但是不知道有哪些好用的工具来使用&#xff0c;对于游戏录制我们其实是需要注意一些事项的&#xff0c;想要观众的观感上比较好就需要把握好视频的帧率等问题&#xff0c;下面我们就来看看录制方法和需要注…

最小二乘问题和非线性优化

最小二乘问题和非线性优化 0.引言1.最小二乘问题2.迭代下降法3.最速下降法4.牛顿法5.阻尼法6.高斯牛顿(GN)法7.莱文贝格马夸特(LM)法8.鲁棒核函数 0.引言 转载自此处&#xff0c;修正了一点小错误。 1.最小二乘问题 在求解 SLAM 中的最优状态估计问题时&#xff0c;我们一般…

RISC-V - 小记

文章目录 关于 RISC-V安装 关于 RISC-V RISC : Reduced Instruction Set Computing RISC-V(“RISC five”)的目标是成为一个通用的指令集架构(ISA) 官网&#xff1a;https://riscv.orggithub : https://github.com/riscv 教程 [完结] 循序渐进&#xff0c;学习开发一个RISC-…

【stm32】初识stm32—stm32环境的搭建

文章目录 &#x1f6f8;stm32资料分享&#x1f354;stm32是什么&#x1f384;具体过程&#x1f3f3;️‍&#x1f308;安装驱动&#x1f388;1&#x1f388;2 &#x1f3f3;️‍&#x1f308;建立Start文件夹 &#x1f6f8;stm32资料分享 我用夸克网盘分享了「STM32入门教程资料…

Maven入职学习

一、什么是Maven&#xff1f; 概念&#xff1a; Maven是一种框架。它可以用作依赖管理工具、构建工具。 它可以管理jar包的规模、jar包的来源、jar包之间的依赖关系。 它的用途就是管理规模庞大的jar包&#xff0c;脱离IDE环境执行构建操作。 具体使用&#xff1a; 工作机…

yolov5代码解读之​detect.py文件【超详细的好吗!点进来看阿很用心的!】

yolov5的代码一直在更新&#xff0c;所以你们代码有些部分可能不太一样&#xff0c;但大差不差。 先给大家看一下项目结构&#xff1a;&#xff08;最好有这个项目&#xff0c;且跑通过&#xff09; detect.py文件&#xff1a;它可以预测视频、图片文件夹、网络流等等。 如何…

Django实现音乐网站 ⑺

使用Python Django框架制作一个音乐网站&#xff0c; 本篇主要是后台对歌手原有实现功能的基础上进行优化处理。 目录 新增编辑 表字段名称修改 隐藏单曲、专辑数 姓名首字母 安装xpinyin 获取姓名首字母 重写保存方法 列表显示 图片显示处理 引入函数 路径改为显示…

EP4CE6E22C8 FPGA最小系统电路原理图+PCB源文件

资料下载地址&#xff1a;EP4CE6E22C8 FPGA最小系统电路原理图PCB源文件 一、原理图 二、PCB

HTTP——八、确认访问用户身份的认证

HTTP 一、何为认证二、BASIC认证BASIC认证的认证步骤 三、DIGEST认证DIGEST认证的认证步骤 四、SSL客户端认证1、SSL 客户端认证的认证步骤2、SSL 客户端认证采用双因素认证3、SSL 客户端认证必要的费用 五、基于表单认证1、认证多半为基于表单认证2、Session 管理及 Cookie 应…

mysql二进制方式升级8.0.34

一、概述 mysql8.0.33 存在如下高危漏洞&#xff0c;需要通过升级版本修复漏洞 Oracle MySQL Cluster 安全漏洞(CVE-2023-0361) mysql/8.0.33 Apache Skywalking <8.3 SQL注入漏洞 二、查看mysql版本及安装包信息 [rootlocalhost mysql]# mysql -V mysql Ver 8.0.33 fo…

class version 61 java version 17.0.4

class version (javap -verbose xxxx.class)_spencer_tseng的博客-CSDN博客

Demystifying Prompts in Language Models via Perplexity Estimation

Demystifying Prompts in Language Models via Perplexity Estimation 原文链接 Gonen H, Iyer S, Blevins T, et al. Demystifying prompts in language models via perplexity estimation[J]. arXiv preprint arXiv:2212.04037, 2022. 简单来说就是作者通过在不同LLM和不同…

程序框架-事件中心模块-观察者模式

一、观察者模式 1.1 观察者模式定义 意图&#xff1a; 定义对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变是&#xff0c;所有依赖于它的对象都能得到通知并自动更新。 适用性&#xff1a; 当一个对象状态的改变需要改变其他对象&#xff0c; 或实际对…

Python自动化实战之使用Pytest进行API测试详解

概要 每次手动测试API都需要重复输入相同的数据&#xff0c;而且还需要跑多个测试用例&#xff0c;十分繁琐和无聊。那么&#xff0c;有没有一种方法可以让你更高效地测试API呢&#xff1f;Pytest自动化测试&#xff01;今天&#xff0c;小编将向你介绍如何使用Pytest进行API自…

8.3day04git+数据结构

文章目录 git版本控制学习高性能的单机管理主机的心跳服务算法题 git版本控制学习 一个免费开源&#xff0c;分布式的代码版本控制系统&#xff0c;帮助开发团队维护代码 作用&#xff1a;记录代码内容&#xff0c;切换代码版本&#xff0c;多人开发时高效合并代码内容 安装g…

设计模式--策略模式(由简单工厂到策略模式到两者结合图文详解+总结提升)

目录 概述概念组成应用场景注意事项类图 衍化过程需求简单工厂实现图代码 策略模式图代码 策略模式简单工厂图代码 总结升华版本迭代的优化点及意义什么样的思路进行衍化的扩展思考--如何理解策略与算法 概述 概念 策略模式是一种行为型设计模式&#xff0c;它定义了算法家族&…