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

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或NULL
    printf("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博客

相关推荐

  1. lua编译器和lua解释lua虚拟机区别

    2024-05-02 07:46:02       12 阅读
  2. 轻量脚本语言Lua配置与c++调用

    2024-05-02 07:46:02       19 阅读
  3. 解释C语言函数及其参数传递方式

    2024-05-02 07:46:02       24 阅读
  4. 简易C语言声明解析(cdecl)——C语言实现

    2024-05-02 07:46:02       45 阅读
  5. Lua-LuaC++交互2

    2024-05-02 07:46:02       16 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-02 07:46:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-02 07:46:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-02 07:46:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-02 07:46:02       20 阅读

热门阅读

  1. 【DevOps】Docker 详细介绍和技术原理

    2024-05-02 07:46:02       13 阅读
  2. 如何在 Apache 中创建自定义 404 页面

    2024-05-02 07:46:02       12 阅读
  3. github的注册和使用

    2024-05-02 07:46:02       12 阅读
  4. 关于阿里云DataWorks的20道面试题

    2024-05-02 07:46:02       12 阅读
  5. C++每日一练——两个数组的交集

    2024-05-02 07:46:02       10 阅读
  6. Cockpit简介

    2024-05-02 07:46:02       13 阅读
  7. AtCoder Beginner Contest 351(补题A~F)

    2024-05-02 07:46:02       11 阅读
  8. 从0到1使用TS实现一个node.js脚手架工具

    2024-05-02 07:46:02       11 阅读
  9. 微信小程序标题设置

    2024-05-02 07:46:02       13 阅读
  10. MongoDB聚合运算符:$substr

    2024-05-02 07:46:02       11 阅读
  11. Stylus介绍

    2024-05-02 07:46:02       13 阅读
  12. Android学习系列目录

    2024-05-02 07:46:02       17 阅读