KRTSt内嵌Lua脚本

KRTSt内嵌Lua脚本

Lua 简介

Lua是一门强大、高效、轻量、可嵌入的脚本语言。它支持多种编程架构:过程编程、面向对象编程(OOP)、函数式编程、数据驱动编程及数据描述。

Lua结合了简洁的过程语法和强大的数据描述结构(基于关联数组和可扩展语义)。Lua使用动态类型,运行时内部通过寄存器式虚拟机(register-based VM)来执行解释字节码,有自动内存管理和分代GC机制,是配置、编写脚本和原型设计的理想选择。

Lua是作为一个C语言编写的库实现的,其被标准C/C++所兼容。Lua的发行版本中包括一个独立程序(就叫 lua),它就是由Lua库所实现,作为一个完整独立的编译/解释器,也可以用于交互式使用或批量执行。Lua志在成为一门强大轻量可嵌入在任何需要的地方的脚本语言,并且是强力但轻便高效的独立语言。

作为扩展语言,Lua没有 主程序 的概念,它通常是 嵌入 到宿主程序中使用,宿主程序也被称为 被嵌入程序 或简称 宿主 (通常宿主程序指上边说到的独立程序lua)。宿主程序可以调用函数来执行一段Lua代码,可以写入或读取Lua变量,也可以注册C函数供Lua代码调用。通过使用C函数,可以在相同的语法框架下来自定义编程语言,从而使得Lua能够应用于广泛的领域。

Lua官网
Lua中文参考手册

功能简介

KRTS内核中内嵌Lua解释器和编译器执行Lua脚本您需要了解KRTS任务处理的相关知识,我们假设您已经学习了相关知识。本实例主要实现的功能是内核成调用Lua脚本执行和Lua脚本调用内核函数并运行;

在这里插入图片描述

工程构建

  • 构建KRTS任务程序(请查阅KRTS任务)

  • 下载Lua源码解压并加入项目中 (Lua 5.4.7源码)

  • 在这里插入图片描述

  • 移植Lua程序,将lua源码文件除了lua.c和luac.c之外,加入到内核工程即可,我是用CMake构建的项目,下面是简单的示例

set(LUA_LIST../3rdparty/lua-5.4.7/lapi.c../3rdparty/lua-5.4.7/lapi.h../3rdparty/lua-5.4.7/lauxlib.c../3rdparty/lua-5.4.7/lauxlib.h../3rdparty/lua-5.4.7/lbaselib.c../3rdparty/lua-5.4.7/lcode.c../3rdparty/lua-5.4.7/lcode.h../3rdparty/lua-5.4.7/lcorolib.c../3rdparty/lua-5.4.7/lctype.c../3rdparty/lua-5.4.7/lctype.h../3rdparty/lua-5.4.7/ldblib.c../3rdparty/lua-5.4.7/ldebug.c../3rdparty/lua-5.4.7/ldebug.h../3rdparty/lua-5.4.7/ldo.c../3rdparty/lua-5.4.7/ldo.h../3rdparty/lua-5.4.7/ldump.c../3rdparty/lua-5.4.7/lfunc.c../3rdparty/lua-5.4.7/lfunc.h../3rdparty/lua-5.4.7/lgc.c../3rdparty/lua-5.4.7/lgc.h../3rdparty/lua-5.4.7/linit.c../3rdparty/lua-5.4.7/liolib.c../3rdparty/lua-5.4.7/ljumptab.h../3rdparty/lua-5.4.7/llex.c../3rdparty/lua-5.4.7/llex.h../3rdparty/lua-5.4.7/llimits.h../3rdparty/lua-5.4.7/lmathlib.c../3rdparty/lua-5.4.7/lmem.c../3rdparty/lua-5.4.7/lmem.h../3rdparty/lua-5.4.7/loadlib.c../3rdparty/lua-5.4.7/lobject.c../3rdparty/lua-5.4.7/lobject.h../3rdparty/lua-5.4.7/lopcodes.c../3rdparty/lua-5.4.7/lopcodes.h../3rdparty/lua-5.4.7/lopnames.h../3rdparty/lua-5.4.7/loslib.c../3rdparty/lua-5.4.7/lparser.c../3rdparty/lua-5.4.7/lparser.h../3rdparty/lua-5.4.7/lprefix.h../3rdparty/lua-5.4.7/lstate.c../3rdparty/lua-5.4.7/lstate.h../3rdparty/lua-5.4.7/lstring.c../3rdparty/lua-5.4.7/lstring.h../3rdparty/lua-5.4.7/lstrlib.c../3rdparty/lua-5.4.7/ltable.c../3rdparty/lua-5.4.7/ltable.h../3rdparty/lua-5.4.7/ltablib.c../3rdparty/lua-5.4.7/ltm.c../3rdparty/lua-5.4.7/ltm.h#../3rdparty/lua-5.4.7/lua.c../3rdparty/lua-5.4.7/lua.h../3rdparty/lua-5.4.7/lua.hpp#../3rdparty/lua-5.4.7/luac.c../3rdparty/lua-5.4.7/luaconf.h../3rdparty/lua-5.4.7/lualib.h../3rdparty/lua-5.4.7/lundump.c../3rdparty/lua-5.4.7/lundump.h../3rdparty/lua-5.4.7/lutf8lib.c../3rdparty/lua-5.4.7/lvm.c../3rdparty/lua-5.4.7/lvm.h../3rdparty/lua-5.4.7/lzio.c../3rdparty/lua-5.4.7/lzio.h
)add_library(${PROJECT_NAME} SHAREDkernel.cpp${LUA_LIST}
)

核心代码

内核代码

  • kernel.cpp
/****************************************           内核层入口**************************************/#include "Base/SharedData.h"
#include "Business/TaskHandle.h"SharedData *kernel_data_ptr_ {nullptr};         // 全局数据指针
KSHandle kernel_shared_data_handle_ {NULL};     // 共享数据句柄// Task处理回调
KSError __stdcall TaskCallback(void * /*pArgs*/, void * /*pContext*/);// KRTS资源初始化
extern "C" KSError __declspec(dllexport) __stdcall InitFunction(void *pArgs, void * /*pContext*/)
{KS_printK("InitFunction called!\n");// 获取全局数据指针kernel_data_ptr_ = static_cast<SharedData *>(pArgs);// 设置任务专用的CPUerror = KS_setTargetProcessor(kernel_data_ptr_->task_cpu,KSF_NO_FLAGS);if (error != KS_OK) { KS_printK("KS_setTargetProcessor failed!\n"); }error = KS_createCallBack(&kernel_data_ptr_->task_callback_handle, TaskCallback, nullptr, KSF_DIRECT_EXEC | KSF_SAVE_FPU, 0);if (error != KS_OK) { return error; }error = KS_setTaskStackSize(0x100000, KSF_NO_FLAGS);if (error != KS_OK) { return error; }error = KS_createTask(&kernel_data_ptr_->task_handle, kernel_data_ptr_->task_callback_handle, 172, KSF_CUSTOM_STACK_SIZE);if (error != KS_OK) { return error; }return KS_OK;
}// KRTS资源析构
extern "C" KSError __declspec(dllexport) __stdcall ExitFunction(void * /*pArgs*/, void * /*pContext*/)
{KS_printK("ExitFunction called!\n");if (kernel_data_ptr_ == nullptr){return KSERROR_FUNCTION_NOT_AVAILABLE;}// 向任务发出终止信号。kernel_data_ptr_->abort = 1;if (kernel_data_ptr_->task_handle != NULL){KS_removeTask(kernel_data_ptr_->task_handle);}if (kernel_data_ptr_->task_callback_handle != NULL){KS_removeCallBack(kernel_data_ptr_->task_callback_handle);}return KS_OK;
}// 这是实时任务将运行的函数,并对执行 Task 操作。只有实时任务才应调用 Task 函数。
KSError __stdcall TaskCallback(void * /*pArgs*/, void * /*pContext*/)
{// 处理循环,此循环仅在发出中止信号时停止。while (true){// 等待停止的通知。if (kernel_data_ptr_->abort != 0) { break; }// Todo 处理 luaif (kernel_data_ptr_->script_run_status){TaskHandle::OnLuaScript();kernel_data_ptr_->script_run_status = false;}KS_sleepTask(REFRESH_TIME*10*1000);}return KS_OK;
}#pragma pack(push, 8)
#include <windows.h>
#pragma pack(pop)BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID pReserved)
{return TRUE;
}

Lua 交互

  • TaskHandle.h
/*****************************************
*
*    lua内核处理
*
*****************************************/#ifndef TASKHANDLE_H
#define TASKHANDLE_Hclass TaskHandle
{
public:TaskHandle();~TaskHandle();//lua 脚本执行static void OnLuaScript();};#endif //TASKHANDLE_H
  • TaskHandle.cpp
#include "TaskHandle.h"
#include "Base/SharedData.h"#pragma pack(push, 8)
extern  "C"
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
#include <iostream>
#pragma pack(pop)// 方法一 :函数注册
static int FunctionTest(lua_State *lua_state)
{// 获取参数个数const int count = lua_gettop(lua_state);int value {};for (int i = 0; i <= count; i++){// 获取参数类型const int type = lua_type(lua_state, i);// 获取参数值value = lua_tonumber(lua_state, i);// 输出printf("index:%d, type:%d, value:%d\n", i, type, value);}lua_pushnumber(lua_state, value);return 1;
}// 方法二:模块注册
static int FunctionModule(lua_State *lua_state)
{// 获取参数个数const int count = lua_gettop(lua_state);double avg {},sum{};for (int i = 0; i <= count; i++){// 获取参数类型const int type = lua_type(lua_state, i);// 获取参数值const double value = lua_tonumber(lua_state, i);printf("index:%d, type:%d, value:%f\n", i, type, value);sum += value;}avg = sum / count;// 返回参数压入栈中lua_pushnumber(lua_state, avg);lua_pushnumber(lua_state, sum);// 返回的参数个数return 2;
}// 列出需要注册的函数数组
static const luaL_Reg KRTS_FunctionModule[] =
{{"FunctionModule", FunctionModule},{nullptr, nullptr}
};// 将所有函数放到表并压入栈中
int CreateLibs(lua_State *lua_state)
{// 创建一个表luaL_newlib(lua_state, KRTS_FunctionModule);return 1;
}// 注册模块
static const luaL_Reg RegisterModule[] = {{ "base", luaopen_base },   // 基础库{ "KRTS", CreateLibs },     //自定义的模块名字:KRTS{ nullptr, nullptr}
};TaskHandle::TaskHandle()
{}TaskHandle::~TaskHandle() = default;void TaskHandle::OnLuaScript()
{try{// 初始化lua_State *lua_state = luaL_newstate();// 加载lua库luaL_openlibs(lua_state);/*****************************************************    方法一: 以函数的形式注册C++普通函数提供给Lua使用*    C++方法: FunctionTest*    lua脚本:*             val = FunctionTest(10)*             print("The value is ", val)****************************************************//* 注册C++函数 */lua_register(lua_state, "FunctionTest", FunctionTest);/******************************************************    方法二: 以模块的方式注册C++普通函数提供给Lua使用*    C++模块: KRTS*       函数: FunctionModule*    lua脚本:*             avg,sum = KRTS.FunctionModule(1,2)*             print("The sum is ", sum)*             print("The avg is ", avg)*****************************************************/for (const luaL_Reg* lua_reg = RegisterModule; lua_reg->func; ++lua_reg){luaL_requiref(lua_state, lua_reg->name, lua_reg->func, 1);lua_pop(lua_state, 1);}//luaL_dostring(lua_state, "print('hello lua')");// 执行lua文件luaL_dofile(lua_state, LUA_FILE_NAME);lua_close(lua_state);}catch (...){printf("lua error\n");}
}

运行结果

index:0, type:4, value:0.000000
index:1, type:3, value:1.000000
index:2, type:3, value:2.000000
The sum is      3.0
The avg is      1.5
--------------------------------
index:0, type:4, value:0
index:1, type:3, value:10
The value is    10.0
--------------------------------

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

《Web性能权威指南》-网络技术概览-读书笔记

注&#xff1a;TCP/IP等知识牵涉面太广&#xff0c;且不说本文&#xff0c;哪怕是原书&#xff0c;限于篇幅&#xff0c;很多知识点都是大致介绍下。如果想深入理解&#xff0c;需要更一步Google相关页面资料。 延迟与带宽 WPO&#xff0c;Web Performance Optimization&…

算法day09 二叉树

class Node<V>{V value;Node left;Node right; } 一、用递归和非递归分别实现二叉树的前序&#xff0c;中序&#xff0c;后序遍历 非递归方式&#xff1a; 前序遍历 根左右 0&#xff09;利用stack后进先出的特点 要输出根左右的顺序&#xff0c;将元素右边先放入栈中…

【CanMV K230】圆形检测

【CanMV K230】圆形检测 什么是圆形检测圆形检测应用领域1.工业自动化2.机器人视觉3.医学图像分析4.目标识别5.质量检测6.研究和开发 K230应用相关函数官方例程HDMI屏幕使用圆形检测 本篇内容&#xff1a; 什么是圆形检测圆形检测应用领域K230应用&#xff08;包含相应函数及例…

SAP学习笔记 - 开发03 - CDSView开发环境搭建,Eclipse中连接SAP,CDSView创建

上一章讲了BTP的账号创建&#xff0c;环境搭建等内容。 SAP学习笔记 - 开发02 - BTP实操流程&#xff08;账号注册&#xff0c;BTP控制台&#xff0c;BTP集成开发环境搭建&#xff09;-CSDN博客 本章继续讲SAP开发。 - CDSView 的开发环境&#xff08;Eclipse&#xff09;搭建…

C++初阶:STL详解(一)——string类

✨✨小新课堂开课了&#xff0c;欢迎欢迎~✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C&#xff1a;由浅入深篇 小新的主页&#xff1a;编程版小新-CSDN博客 1.为什么会有string类 C 语言中&#xff0c…

驾驭不断发展的人工智能世界

从很多方面来看&#xff0c;历史似乎正在重演。许多企业正争相采用生成式人工智能 (Gen AI)&#xff0c;就像它们争相采用云计算一样&#xff0c;原因也是一样的&#xff1a;效率、成本节约和竞争优势。 然而&#xff0c;与云一样&#xff0c;GenAI 仍是一项发展中的技术&…

Kafka 分布式消息系统详细介绍

Kafka 分布式消息系统 一、Kafka 概述1.1 Kafka 定义1.2 Kafka 设计目标1.3 Kafka 特点 二、Kafka 架构设计2.1 基本架构2.2 Topic 和 Partition2.3 消费者和消费者组2.4 Replica 副本 三、Kafka 分布式集群搭建3.1 下载解压3.1.1 上传解压 3.2 修改 Kafka 配置文件3.2.1 修改z…

网络原理之TCP协议(万字详解!!!)

目录 前言 TCP协议段格式 TCP协议相关特性 1.确认应答 2.超时重传 3.连接管理&#xff08;三次握手、四次挥手&#xff09; 三次握手&#xff08;建立TCP连接&#xff09; 四次挥手&#xff08;断开连接&#xff09; 4.滑动窗口 5.流量控制 6.拥塞控制 7.延迟应答…

gazebo 已加载模型但无法显示

目录 写在前面的话问题一&#xff1a;robot_state_publisher 发布机器人信息失败报错一 Error: Error document empty.报错二 .xcaro 文件中有多行注释成功启动 问题二&#xff1a;通过 ros2 启动 gazebo 失败成功启动 问题三&#xff1a;gazebo 崩溃和无法显示模型问题四&…

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证&#xff1a;Authentication1.2 鉴权&#xff1a;Authorization1.3 准入控制&#xff1a;Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes…

Pr:首选项 - 音频

Pr菜单&#xff1a;编辑/首选项 Edit/Preferences Premiere Pro 首选项中的“音频” Audio选项卡主要作用是控制音频的处理设置&#xff0c;包括音量调整、波形生成、音频渲染等选项&#xff0c;这些设置有助于优化音频的处理和编辑工作&#xff0c;适用于不同的剪辑需求和项目…

VS Code 调试go程序的相关配置说明

用 VS code 调试Go程序需要在.vscode/launch.json文件中增加如下配置&#xff1a; // launch.json {// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// For more information, visit: https://go.microsoft.…

RISC-V (十二)系统调用

系统模式&#xff1a;用户态和内核态 当前的代码都是实现在machine模式下。 系统模式的切换 epc寄存器的值存放的是ecall指本身的地址 。 用ecall指令 系统调用的执行流程 mret这条指令会利用status的mpp值恢复到之前的特权级别。 蓝色的线表示涉及到权限切换。 系统调用的传…

想要从OPPO手机恢复数据?免费OPPO照片视频恢复软件

此实用程序可帮助那些寻找以下内容的用户&#xff1a; 在OPPO手机中格式化存储卡后可以恢复图片吗&#xff1f;我删除了 OPPO上的视频和图片&#xff0c;我感觉很糟糕&#xff0c;因为里面有我在拉斯维加斯拍摄的视频和照片 免费OPPO照片视频恢复软件 您能恢复OPPO上已删除的…

JavaScript拷贝的艺术:玩转深拷贝和浅拷贝

前言 在实际的项目开发中&#xff0c;我们时刻都在使用数据拷贝功能&#xff0c;赋值、深拷贝和浅拷贝是前端开发中常见的概念&#xff0c;用于复制简单数据类型&#xff08;字符串、数值、布尔值&#xff09;和引用类型&#xff08;对象、数组&#xff09;。它们的主要区别在…

spring中添加@Test注解测试

1、添加maven依赖 <!-- 添加test方便测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><dependency><grou…

C语言进阶版第8课—指针(2)

文章目录 1. 数组名的理解2. 指针访问数组3. 一维数组传参本质4. 冒泡排序5. 二级指针6. 指针数组7. 指针数组模拟二维数组 1. 数组名的理解 sizeof&#xff08;数组名&#xff09;— 这里的数组名代表整个数组&#xff0c;计算的也是整个数组的大小&数组名 — 这里的数组名…

HTML 基础,尚优选网站设计开发(二)

最近在恶补HTML相关知识点&#xff0c;本人是后端程序员&#xff0c;看到周围很多人都被裁员了&#xff0c;突然想尽早转变成全栈程序员变成独立开发者&#xff0c;有空余接接私单、商单的 尚优选网站设计开发&#xff0c;HTMLCSSJavaScript实际使用 尚优选网站设计开发页面分析…

KDD 2024 时空数据(Spatio-temporal) Research论文总结

2024 KDD&#xff08; ACM SIGKDD Conference on Knowledge Discovery and Data Mining, 知识发现和数据挖掘会议&#xff09;在2024年8月25日-29日在西班牙巴塞罗那举行。 本文总结了KDD2024有关时空数据(Spatial-temporal) 的相关论文&#xff0c;如有疏漏&#xff0c;欢迎大…

初步了解VTK装配体

VTK还不太了解&#xff0c;根据资料&#xff0c; vtk.vtkAssembly 是 VTK库中的一个重要类&#xff0c;允许通过将多个vtkActor对象组合在一起来创建复杂的3D模型。 import vtk import math from vtk.util.colors import *filenames ["cylinder.stl","sphere…