Qt 如何搭建Lua的运行环境

一、Lua简介

Lua 是一种强大的、高效的、轻量级的、可嵌入的脚本语言。它支持过程(procedural)编程、面向对象编程、函数式编程以及数据描述。Lua 是动态类型的,运行速度快,支持自动内存管理,因此被广泛用于配置、脚本编写等场景。

二、Lua的优势

Lua脚本可以很容易的被C/C++ 代码调用,也可以反过来调用C/C++的函数,这使得Lua在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替XML、ini等文件格式,并且更容易理解和维护。 Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译、运行。 一个完整的Lua解释器不过200k,在所有脚本引擎中,Lua的速度是最快的。这一切都决定了Lua是作为嵌入式脚本的最佳选择。

三、Qt + Lua 环境搭建

Lua是用标准C编写的,所以几乎常见的编程环境它都能编译Lua。下载源码包后,直接编译即可。

1、 下载Lua

下载地址:https://www.lua.org/ftp
在这里插入图片描述

2、 使用QtCreator编译lua.a库

打开QtCreator,新建项目 > Library > C++库,在后续弹出的窗口中选择 Statically Linked Library,根据向导完成项目的创建,然后删掉由向导添加的头文件和源文件。将除了lua.c和luac.c以外的文件加入到你的开发环境中进行编译即可。(文末有对应的pro文件,可以参考一下。)
ps:lua.c 和 luac.c 中都有main函数,需要分别编译这两个文件。其中,lua.c编译出来是解析器,luac.c编译出来是编译器。

四、在Qt中调用Lua

1、 新建一个math.lua文件,内容如下:

function fn_add(x,y)
    return x + y
end

function fn_subtract(x,y)
    return x - y
end

function fn_multiply(x,y)
    return x * y
end

function fn_divide(x,y)
    return x*1.0 / y
end

2、Qt调用Lua的测试代码

新建Qt控制台程序,在该控制台程序的pro文件,配置一下lua库的头文件以及库文件路径:

CONFIG(debug, debug|release){
    DESTDIR = $$PWD/../bin/debug
    OBJECTS_DIR += $$PWD/../obj/debug
    DIR_NAME = debug
}
CONFIG(release, debug|release){
    DESTDIR = $$PWD/../bin/release
    OBJECTS_DIR += $$PWD/../obj/release
    DIR_NAME = release
}
INCLUDEPATH  += $$PWD/./3rdparty/libLua/include
LIBS += -L$$PWD/./3rdparty/libLua/lib/$${DIR_NAME}/ -lliblua

控制台main.cpp的代码如下:

#include <QCoreApplication>
#include <stdio.h>
extern "C"{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}

lua_State *L;
double luaMath(std::string fname, int x, int y)
{
    /* 要调用一个函数请遵循以下协议:
     * 首先,要调用的函数应该被压入栈,接着把需要传递给这个函数的参数按正序压栈,
     * 这是指第一个参数首先压栈。最后调用一下 lua_call,当函数调用完毕后,
     * 所有的参数以及函数本身都会出栈,而函数的返回值这时则被压栈。*/

    double result;
    /*获取函数名*/
    lua_getglobal(L, fname.c_str());

    /*压入第一个参数*/
    lua_pushnumber(L, x);

    /*压入第二个参数*/
    lua_pushnumber(L, y);

    /*使用2个参数调用函数,返回1个结果。*/
    lua_call(L, 2, 1);

    /*获取结果*/
    result = (double)lua_tonumber(L,-1);

    /*清理返回结果*/
    lua_pop(L, 1);

    return result;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    L =  luaL_newstate();//新建lua解释器
    luaL_openlibs(L);//载入lua基础库

#if 1
    //执行lua脚本:
    luaL_dofile(L, "lua/math.lua");//填写实际的math.lua文件的相对路径

    /*call the add function*/
    int sum = luaMath("fn_add", 10, 15);
    printf("sum = %d\r\n", sum);

    int subtract = luaMath("fn_subtract", 10, 15);
    printf("subtract = %d\r\n", subtract);

    int multiply = luaMath("fn_multiply", 10, 15);
    printf("multiply = %d\r\n", multiply);

    auto divide = luaMath("fn_divide", 10, 15);
    printf("divide = %.3f\r\n", divide);
#endif

    /*cleanup Lua*/
    lua_close(L);

    system("pause");
    return a.exec();
}

3、输出结果

sum = 25
subtract = -5
multiply = 150
divide = 0.667

五、附上lua库的pro文件内容:

QT -= gui

TEMPLATE = lib
CONFIG += staticlib

CONFIG += c++11

#去掉生成空的debug和release目录
CONFIG -= debug_and_release

# 编译时临时文件路径
RCC_DIR += $$PWD/../temp/rcc_tmp
MOC_DIR += $$PWD/../temp/moc_tmp
UI_DIR  += $$PWD/../temp/ui_tmp

CONFIG(debug, debug|release){
    DESTDIR = $$PWD/../lib/debug
    OBJECTS_DIR += $$PWD/../obj/debug
    DIR_NAME = debug
}
CONFIG(release, debug|release){
    DESTDIR = $$PWD/../lib/release
    OBJECTS_DIR += $$PWD/../obj/release
    DIR_NAME = release
}

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    lapi.c \
    lauxlib.c \
    lbaselib.c \
    lcode.c \
    lcorolib.c \
    lctype.c \
    ldblib.c \
    ldebug.c \
    ldo.c \
    ldump.c \
    lfunc.c \
    lgc.c \
    linit.c \
    liolib.c \
    llex.c \
    lmathlib.c \
    lmem.c \
    loadlib.c \
    lobject.c \
    lopcodes.c \
    loslib.c \
    lparser.c \
    lstate.c \
    lstring.c \
    lstrlib.c \
    ltable.c \
    ltablib.c \
    ltm.c \
    lundump.c \
    lutf8lib.c \
    lvm.c \
    lzio.c

HEADERS += \
    lapi.h \
    lauxlib.h \
    lcode.h \
    lctype.h \
    ldebug.h \
    ldo.h \
    lfunc.h \
    lgc.h \
    ljumptab.h \
    llex.h \
    llimits.h \
    lmem.h \
    lobject.h \
    lopcodes.h \
    lopnames.h \
    lparser.h \
    lprefix.h \
    lstate.h \
    lstring.h \
    ltable.h \
    ltm.h \
    lua.h \
    lua.hpp \
    luaconf.h \
    lualib.h \
    lundump.h \
    lvm.h \
    lzio.h

# Default rules for deployment.
unix {
    target.path = $$[QT_INSTALL_PLUGINS]/generic
}
!isEmpty(target.path): INSTALLS += target

#拷贝头文件到include目录下
win32 {
    SrcIncludeDir = $${PWD} #定义的宏变量,在非首位置使用时需要带{}
    SrcIncludeDir = $$replace(SrcIncludeDir, /, \\)
    DstIncludeDir = $$PWD/../include/
    DstIncludeDir = $$replace(DstIncludeDir, /, \\)
    #多条命令语句之间可以用&&隔开,自动连续执行
    QMAKE_POST_LINK += echo "---------prepare to copy *.h---------" && echo.
    QMAKE_POST_LINK += cd $$SrcIncludeDir &&  xcopy /s/y/i $$SrcIncludeDir\lauxlib.h $$DstIncludeDir
    QMAKE_POST_LINK += &&  xcopy /s/y/i $$SrcIncludeDir\lua.h $$DstIncludeDir
    QMAKE_POST_LINK += &&  xcopy /s/y/i $$SrcIncludeDir\luaconf.h $$DstIncludeDir
    QMAKE_POST_LINK += &&  xcopy /s/y/i $$SrcIncludeDir\lualib.h $$DstIncludeDir

    #打印测试
    #message("--SrcIncludeDir= $$SrcIncludeDir")
    #message("--DstIncludeDir= $$DstIncludeDir")
}

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

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

相关文章

java-集合工具类Collections

我们在使用它的时候记得导包 常见API 我们就简单看看第一第二个方法&#xff0c;代码如下&#xff0c;其余的知道用就行

基于经验模式分解和小波阈值的自适应降噪研究_杨铮

目的 针对轴承信号在采集过程中容易受到不同环境下噪声干扰&#xff0c;提出EMD分解结合小波阈值的自适应降噪的方法&#xff0c;对轴承振动信号进行降噪处理&#xff0c;提取出所需要的振动信号。方法 首先对含有噪声的轴承信号进行EMD分解&#xff0c;得到n个IMF并进行小波阈…

GUROBI之数学启发式算法Matheuristics

参考运小筹的帖子&#xff1a;优化求解器 | Gurobi 数学启发式算法&#xff1a;参数类型与案例实现 - 知乎 (zhihu.com) 简言之&#xff0c;数学启发式是算法就是数学规划和启发式算法的融合&#xff0c;与元启发式算法相比&#xff0c;数学启发式算法具有更强的理论性。 在GUR…

C++初阶

1.缺省参数 给缺省参数的时候&#xff0c;不能声明&#xff0c;定义同时给&#xff0c;只能声明的时候给缺省参数&#xff0c;同时给程序报错&#xff1b; 2.函数重载 C语言不允许同名函数的存在&#xff0c;函数名不能相同&#xff0c;C引入函数重载&#xff0c;函数名可以…

SOLIDWORKS 2024新版价格 SOLIDWORKS2024专业版白金版多少钱?

达索 SOLIDWORKS 一直以来都致力于让每位设计师和工程师的设计都触手可及。SOLIDWORKS贯彻的使命就是通过功能强大且易于使用的产品开发解决方案&#xff0c;在创造、协作和提供创新的产品体验方面助您一臂之力。SOLIDWORKS 2024延续了这一期望&#xff0c;同时开启了强化使用S…

Altium Designer快速入门及项目实战教程之PCB设计(四)

一、引言 在我们的Altium Designer系列教程中&#xff0c;我们已经一起走过了软件界面的初识、原理图的绘制&#xff0c;以及元件库的建立。今天&#xff0c;我们将进入这一系列教程的高潮部分——PCB设计。 PCB设计不仅是电子产品开发过程中的核心&#xff0c;也是检验一个电…

Maven项目添加依赖

maven仓库&#xff1a;Maven Repository: Search/Browse/Explore (mvnrepository.com) 1.在maven仓库中搜素自己想要的依赖&#xff0c;选择合适的版本号&#xff0c;复制以下内容(依赖坐标)。 2.在pom.xml中把复制的粘贴进去。刷新。&#xff08;注意内容要放在dependencies双…

修改表结构

目录 修改表结构 创建数据表插入数据 修改已有列 修改 member 表的 name 列的定义 为表增加列 增加一个 address 列&#xff0c;这个列上不设置默认值 增加一个 sex 列&#xff0c;这个列上设置默认值 删除表中的列 删除 sex 列 Oracle从入门到总裁:​​​​​​https…

西门子PLCS7-1200位逻辑指令的使用

1.LAD触点 常开触点的位值为1时&#xff0c;常开触点将闭合&#xff08;ON&#xff09;。位值为0时&#xff0c;常开触点将闭合&#xff08;OFF&#xff09;。 常闭触点的位值为1时&#xff0c;常闭触点将闭合&#xff08;OFF&#xff09;。位值为0时&#xff0c;常闭触点将闭…

一文掌握mysql中的查询语句

目录 1. 聚合查询1.1 聚合函数1.2 GROUP BY子句1.3 HAVING 2. 联合查询2.1 内连接2.2 外连接2.3 自连接2.4 子查询2.5 合并查询 1. 聚合查询 1.1 聚合函数 常见的统计总数、计算平局值等操作&#xff0c;可以使用聚合函数来实现&#xff0c;常见的聚合函数有&#xff1a; 函…

从0到1:如何用AI完成高质量的科研论文写作?

人工智能革命&#xff1a;如何让聊天机器人更懂你 人工智能正在以其强大的数据处理和语言生成能力改变世界。在学术界&#xff0c;大语言模型&#xff08;LLM&#xff09;为科学交流带来了一种新的工具。我们旨在有效地将AI工具与学术写作相结合&#xff0c;以更有效和更有影响…

关于图在推荐系统中的研究

业界最新的论文 Intent-aware Recommendation via Disentangled Graph Contrastive Learning 作者&#xff1a;Yuling Wang, Xiao Wang, Xiangzhou Huang, Yanhua Yu, Haoyang Li, Mengdi Zhang, Zirui Guo, Wei Wu 地址&#xff1a;https://arxiv.org/abs/2403.03714 论文…

Java毕业设计-基于spring boot开发的实习管理系统-毕业论文+答辩ppt(附源代码+演示视频)

文章目录 前言一、毕设成果演示&#xff08;源代码在文末&#xff09;二、毕设摘要展示1.开发说明2.需求分析3、系统功能结构 三、系统实现展示1、前台功能模块2、后台功能模块2.1 管理员功能2.2 教师功能2.3 学生功能2.4 实习单位功能 四、毕设内容和源代码获取总结 Java毕业设…

Ps:清理

清理 Purge命令位于“编辑”菜单下&#xff0c;它主要用于释放 Photoshop 使用的内存资源&#xff0c;有助于提高系统的性能。 通过使用“清理”命令&#xff0c;用户可以有效管理 Photoshop 的资源使用&#xff0c;特别是在处理大型文件或进行长时间编辑会话时。 定期清理可以…

科研学习|论文解读——一种修正评分偏差并精细聚类中心的协同过滤推荐算法

知网链接 一种修正评分偏差并精细聚类中心的协同过滤推荐算法 - 中国知网 (cnki.net) 摘要 协同过滤作为国内外学者普遍关注的推荐算法之一&#xff0c;受评分失真和数据稀疏等问题影响&#xff0c;算法推荐效果不尽如人意。为解决上述问题&#xff0c;本文提出了一种改进的聚类…

web项目的搭建

使用Webstorm并创建Next.js文件 1、配置nodejs环境、安装webstorm【配置node.js可以使用nvm去管理nodejs的版本】 2、需要破解webstorm&#xff0c;可能会导致原本的idea失效&#xff0c;注册码过期 3、taobao的npm过期&#xff0c;导致npm is sass执行不成功&#xff0c;需…

openAI key 与ChatGPTPlus的关系,如何升级ChatGPTPLus

一、前言 先详细介绍一下Plus会员和Open API之间的区别&#xff1a; 实际上&#xff0c;这两者是相互独立的。举例来说&#xff0c;虽然您开通了Plus会员&#xff0c;并不意味着您就可以使用4.0版本的API。尽管这两个账户可以是同一个&#xff0c;但它们是完全独立的平台。 …

Linux信号机制(二)

目录 一、信号的阻塞 二、信号集操作函数 三、sigprocmask函数 四、pause函数 五、sigsuspend函数 一、信号的阻塞 有时候不希望在接到信号时就立即停止当前执行&#xff0c;去处理信号&#xff0c;同时也不希望忽略该信号&#xff0c;而是延时一段时间去调用信号处理函数。…

媒体单位专用小记者报名及各类活动报名系统介绍

媒体单位专用小记者报名及各类活动报名系统介绍 小记者活动鼓励孩子们关注生活和社会&#xff0c;丰富成长体验&#xff0c;开启心智&#xff0c;淬砺思想。这不仅有助于提高他们的理性思辨力&#xff0c;还能培养他们的社会责任感和公民意识。小记者活动为学生提供了一个全新…

[密码学]OpenSSL实践篇

背景 最近在写Android abl阶段fastboot工具&#xff0c;需要我在Android代码中实现一些鉴权加解密相关的fastboot命令&#xff0c;里面用到了OpenSSL。我们先来实践一下OpenSSL在Linux系统中的指令。 OpenSSL官方网站&#xff1a;OpenSSL 中文手册 | OpenSSL 中文网 1. 查看…