C语言嵌入Lua解释器的方法

server/2024/10/18 2:30:31/

Lua语言是一个轻量的脚本语言,可以用很少的资源运行其解释器

C语言是一个很常用的语言,广泛用于嵌入式等底层场景

这两个语言结合,可以应用于嵌入式等多个场景。比如,一些硬件公司会允许开发者使用Lua语言操作其硬件

Lua的安装

这里所指的Lua的安装,就是从Lua: download中下载Lua的源代码,并将其复制粘贴到你的项目中:

解压文件后,进入src目录:

新建一个项目文件夹,然后将src目录中除了lua.c、luac.c的代码文件都复制到项目文件夹中。

然后新建main.c,写入如下代码:

#include <stdio.h>
#include <stdlib.h>#include "lua/src/lua.h"     // Lua数据类型与函数接口
#include "lua/src/lauxlib.h" // Lua与C交互辅助函数接口
#include "lua/src/lualib.h"  // Lua标准库打开接口int main(void){lua_State* L = luaL_newstate();luaL_openlibs(L);                         // 打开标准库luaL_dostring(L, "print('Hello World')"); // 解析并执行Lua脚本字符串lua_close(L);                             // 关闭Lua线程return 0;
}

 编译的时候要注意把lua的源码也编译进去:

gcc main.c ./lua/src/*.c

最后输出:

Hello World

Lua栈

Lua在运行时,有自己的Lua栈,可以使用luaL_newstate()创建一个新的Lua栈:

lua_State* L = luaL_newstate();

可以使用lua_pushXXX压入指定数据类型的数据、lua_isXXX判断某个索引的值是否为指定数据类型,lua_toXXX获得某个索引的值是否为特定类型:

#include <stdio.h>
#include <stdlib.h>#include "lua/src/lua.h"     // Lua数据类型与函数接口
#include "lua/src/lauxlib.h" // Lua与C交互辅助函数接口
#include "lua/src/lualib.h"  // Lua标准库打开接口int main(void){lua_State* L = luaL_newstate();printf("Top index: %d\n", lua_gettop(L)); // 返回当前栈顶索引(等于栈中元素个数)lua_pushnumber(L, 233);                   // 压数据入栈lua_pushstring (L, "Hello World");              // 压数据入栈printf("Top index: %d\n", lua_gettop(L));printf("Index 2: %s\n", lua_tostring(L, 2));  // 将栈中数据转换成C语言数据printf("Index 1: %d\n", lua_tointeger(L, 1)); // 将栈中数据转换成C语言数据// 这类转换如果失败则给出默认值0或NULLprintf("Top index: %d\n", lua_gettop(L));lua_pop(L, 1);                            // 从栈中弹出一个值printf("Top index: %d\n", lua_gettop(L));lua_settop(L, 0);                         // 清空栈printf("Top index: %d\n", lua_gettop(L));lua_close(L);}

Lua语言调用C语言函数

在Lua中调用的C语言函数必须是

int (*)(lua_State *)

类型的,比如:

int func(lua_State *L){}

 使用之前,需要先调用lua_register()函数注册C函数:

lua_register(L, "cfunc", func);

然后调用lua_dostring()执行lua脚本:

luaL_dostring(L, "cfunc()");

 完整代码如下:

#include <stdio.h>
#include <stdlib.h>#include "lua/src/lua.h"     // Lua数据类型与函数接口
#include "lua/src/lauxlib.h" // Lua与C交互辅助函数接口int func(lua_State *L){const char *str = lua_tostring(L, 1);printf("lua want to print : %s\n", str);return 0;
}int main(void){lua_State* L = luaL_newstate();lua_register(L, "cfunc", func);luaL_dostring(L, "cfunc('Hello World')");lua_close(L);}

C语言调用Lua语言函数

C语言调用Lua函数通过栈实现:

#include <stdio.h>
#include <stdlib.h>
#include "lua/src/lua.h"
#include "lua/src/lauxlib.h"
#include "lua/src/lualib.h"// 下面定义了一个lua函数,传入两个参数并打印,返回22,33
const char *lua_code = "\function lua_func(arg1, arg2)\print(arg1, arg2)\return 22, 33\end\
";int main() {lua_State* L = luaL_newstate();luaL_openlibs(L);luaL_dostring(L, lua_code);  // 加载自定义的lua函数到全局变量printf("Top index: %d\n", lua_gettop(L));lua_getglobal(L, "lua_func"); // 从全局变量中获取自定义lua函数压入栈中lua_pushinteger(L, 666);      // 向栈中压入参数lua_pushinteger(L, 777);      // 向栈中压入参数printf("Top index: %d\n", lua_gettop(L));lua_call(L, 2, LUA_MULTRET);        // 调用已压入栈中的lua函数,传入2个参数,并将所有返回值压入栈中// lua_call调用函数本身会清空当前栈,然后再将返回值压入栈printf("Top index: %d\n", lua_gettop(L));printf("Index 1: %s\n", lua_tostring(L, 1)); // 打印lua函数返回值printf("Index 2: %s\n", lua_tostring(L, 2)); // 打印lua函数返回值lua_close(L);return 0;
}

参考

Lua和C语言交互入门_c调用 lua-CSDN博客

GCC编译步骤、动态库和静态库的创建和使用、ELF库简介及查看方法_gcc编译静态库-CSDN博客


http://www.ppmy.cn/server/28348.html

相关文章

迁移学习修改最后把一层类别数

参考以下代码 def create_model(aux, num_classes, pretrainTrue):model deeplabv3_resnet50(auxaux, num_classesnum_classes)if pretrain:weights_dict torch.load("./deeplabv3_resnet50_coco.pth", map_locationcpu)if num_classes ! 21:# 官方提供的预训练权…

【c++】反向迭代器的探究实现

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 在list中我们实现了正向的迭代器&#xff0c;学习完优先级队列后&#xff0c;我们也对适配器模式有了一个深刻的理解&#xff0c;这篇文章基于这种模式下&#xff0c;实现各类容器的反向迭…

利用二叉检索树将文章中的单词建立索引(正则表达式)

知识储备 链接: 【二叉检索树的实现——增删改查、读取命令文件、将结果写入新文件】 1、正则表达式的处理 &#xff08;1&#xff09;r’前缀的作用 r’前缀的用于定义原始字符串&#xff0c;特点是不会处理反斜杠\作为转义字符 &#xff08;2&#xff09;正则表达式中元…

25计算机考研院校数据分析 | 同济大学

同济大学&#xff08;Tongji University&#xff09;&#xff0c;简称“同济”&#xff0c;是中华人民共和国教育部直属&#xff0c;由教育部、国家海洋局和上海市共建的全国重点大学&#xff0c;是历史悠久、享有盛誉的中国著名高等学府&#xff0c;是国家“双一流”、“211工…

Spring Cloud原理详解

在计算机专业领域&#xff0c;微服务架构已成为一种广泛应用的分布式系统解决方案。而在实现微服务架构的过程中&#xff0c;Spring Cloud以其强大的功能和良好的扩展性赢得了广泛的认可。 一、Spring Cloud概述 Spring Cloud是一系列框架的集合&#xff0c;它利用Spring Boo…

利用Triple U.Net结构对冷冻切片HE染色组织学图像进行核实例分割

利用Triple U.Net结构对冷冻切片H&E染色组织学图像进行核实例分割 摘要IntroductionRelated WorksDatasetProposed MethodologyDataset PreparationSegmentation BranchLoss FunctionWatershed Algorithm Nuclei Instance Segmentation of Cryosectioned H&E Stained H…

Node.js使用

Node.js是一个基于Chrome V8引擎的JavaScript运行环境&#xff0c;它使得JavaScript能够脱离浏览器&#xff0c;直接在服务器端运行。Node.js的异步I/O模型使其在处理高并发请求时表现出色&#xff0c;适用于构建网络应用、实时应用等。以下是对Node.js使用的总结&#xff1a; …

【3GPP IAB】 3GPP支持IAB架构概述

1 概述 IAB用于回传链路的无线传输&#xff0c;对于NR高频尤其重要&#xff0c;3GPP协议讨论了IAB的可能架构和部署方式&#xff0c;一起来看看吧。 2 IAB 功能和接口 IAB尽量重用为接入定义的现有功能和接口。特别是&#xff0c;移动终端(MT)、gNB- DU、gNB- CU、UPF、AMF和S…