第一个示例

简介: 第一个示例

环境准备

提示

我们以 Lua 5.3.5 版本为例,操作系统为 Ubuntu 20.04 ,使用多版本的方式安装 Lua 5.3.5 ,编辑器为 VSCode ,使用 GCC 编译。


新建工程目录( demo 文件夹),将官网上下载下来的 Lua 5.3.5 版本压缩包解压,将其中的 src 文件夹拷贝到 demo 文件夹下,并改名为 lua-5.3.5 。接下来配置 .vscode 文件夹内的 c_cpp_properties.jsonextensions.jsonsettings.json 文件,具体详见案例工程。


代码编写

建立 main.c 文件,写入如下内容:

#include <stdio.h>
#include <string.h>
#include "lauxlib.h"
#include "lua.h"
#include "lualib.h"
int main(void) {
  char buff[256];
  int error;
  lua_State *L = luaL_newstate();  // 打开Lua
  luaL_openlibs(L);                // 打开L标准库
  while (fgets(buff, sizeof(buff), stdin) != NULL) {
    error = luaL_loadstring(L, buff) || lua_pcall(L, 0, 0, 0);
    if (error) {
      fprintf(stderr, "%s\n", lua_tostring(L, -1));
      lua_pop(L, 1);  // 从栈中弹出错误信息
    }
  }
  lua_close(L);
  return 0;
}


编译运行

编译参考:https://blog.csdn.net/shjhuang/article/details/104548185

$ gcc -o main main.c /usr/local/lua-5.3.5/lib/liblua.a -ldl -lm -I lua-5.3.5
$ ./main
# 接下来会进入交互模式,可以将其认为是Lua的交互模式,输入代码得到信息
> a = "hello Iric"
> print(a)          --> hello Iric
> local a = 1; local b = 2; print(a + b)      --> 3


提示

/usr/local/lua-5.3.5/lib/liblua.aLua 编译安装后才有的,我这里是使用了多版本的方式安装了 Lua 5.3.5 ,因此才是这个路径,如果采用单版本apt 等其他方式,可以采用 $ locate liblua.a 命令来查询文件位置。


说明

头文件 lua.h 声明了 Lua 提供的基础函数,其中包括创建新 Lua 环境的函数、调用 Lua 函数的函数、读写环境中的全局变量的函数,以及注册供 Lua 语言调用的新函数的函数等等。 lua.h 中声明的所有内容都有一个前缀: lua_ 。例如: lua_pcall


头文件 lauxlib.h 声明了辅助库auxiliary libraryauxlib )所提供的函数,其中所有的声明均以 luaL_ 开头,例如: luaL_loadstring 。辅助库使用 lua.h 提供的基础 API 来提供更高层次的抽象,特别是对标准库用到的相关机制进行抽象。基础 API 追求经济性正交性orthogonality ),而辅助库则追求对常见任务的实用性。当然,要在程序中创建其他所需要的抽象也是非常简单的。


请记住

辅助库不能访问 Lua 的内部元素,而只能通过 lua.h 中声明的官方基础 API 完成所有工作。辅助库能实现什么,你的程序就能实现什么。


Lua 标准库没有定义任何 C 语言全局变量,它将其所有的状态都保存在动态的结构体 lua_State 中, Lua 中的所有函数都接收一个指向该结构的指针作为参数。这种设计使得 Lua 是可重入的,并且可以直接用于编写多线程代码。


顾名思义,函数 luaL_newstate 用于创建一个新的 Lua 状态。当它创建一个新状态时,新环境中没有包含预定义的函数,甚至连 print 也没有。为了保持 Lua 语言的精炼,所有的标准库都被组织成不同的包,这样我们在不需要使用某些包时可以忽略他们。头文件 lualib.h 中声明了用于打开这些库的函数。函数 luaL_openlibs 用于打开所有的标准库。


当创建好一个状态并在其中加载标准库以后,就可以处理用户的输入了。程序会首先调用函数 luaL_loadstring 来编译用户输入的每一行内容,如果没有错误,则返回,并向中压入编译后得到的函数。然后,程序调用 lua_pcall 从栈中弹出编译后的函数,并以保护模式protected mode )运行。与函数 luaL_loadstring 类似,如果没有错误发生,函数 lua_pcall 返回;当发生错误时,这两个函数都会向栈中压入一条错误信息。随后我们可以通过函数 lua_tostring 获取错误信息,并在打印出错误信息后使用函数 lua_pop 将其从栈中删除。


错误处理

C 语言中,真实的错误处理可能会相当复杂,并且如何处理错误取决于应用的性质。 Lua 核不会直接向任何输出流写入数据,它只会通过返回错误性信息来提示错误。每个应用可以用其所需的最恰当的方式来处理这些信息。为了简化讨论,假设以下示例使用如下简单的错误处理函数,即打印一条错误信息,关闭 Lua 状态并结束整个应用:

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
void error (lua_State *L, const char *fmt, ...){
  va_list argp;
  va_start(argp, fmt);
  vfprintf(stderr, fmt, argp);
  va_end(argp);
  lua_close(L);
  exit(EXIT_FAILURE);
}


C++编译

由于 Lua 既可以作为 C 代码来编译,也可以作为 C++ 代码来编译,因此 lua.h 中并没有包含以下这种在 C 标准库中的常见的写法:

#ifdef __cplusplus
extern "C" {
#endif
  ...
#ifdef __cplusplus
}
#endif


如果将 Lua 作为 C 代码编译出来后又要在 C++ 中使用,那么可以引入 lua.hpp 来替代 lua.h 。定义如下:

extern "C" {
  #include "lua.h"
}
目录
相关文章
|
7天前
|
人工智能 运维 安全
|
5天前
|
人工智能 异构计算
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
|
6天前
|
机器学习/深度学习 人工智能 自然语言处理
B站开源IndexTTS2,用极致表现力颠覆听觉体验
在语音合成技术不断演进的背景下,早期版本的IndexTTS虽然在多场景应用中展现出良好的表现,但在情感表达的细腻度与时长控制的精准性方面仍存在提升空间。为了解决这些问题,并进一步推动零样本语音合成在实际场景中的落地能力,B站语音团队对模型架构与训练策略进行了深度优化,推出了全新一代语音合成模型——IndexTTS2 。
607 21
|
12天前
|
人工智能 JavaScript 测试技术
Qwen3-Coder入门教程|10分钟搞定安装配置
Qwen3-Coder 挑战赛简介:无论你是编程小白还是办公达人,都能通过本教程快速上手 Qwen-Code CLI,利用 AI 轻松实现代码编写、文档处理等任务。内容涵盖 API 配置、CLI 安装及多种实用案例,助你提升效率,体验智能编码的乐趣。
970 110
|
6天前
|
人工智能 测试技术 API
智能体(AI Agent)搭建全攻略:从概念到实践的终极指南
在人工智能浪潮中,智能体(AI Agent)正成为变革性技术。它们具备自主决策、环境感知、任务执行等能力,广泛应用于日常任务与商业流程。本文详解智能体概念、架构及七步搭建指南,助你打造专属智能体,迎接智能自动化新时代。