一、环境与准备工作
测试环境:win10
编译器:mingw
QT版本:QT5.12.3
下载ZeroBraneStudio:(博主这边下载的是2.01版本)
https://studio.zerobrane.com/
将"ZeroBraneStudioEduPack-2.01-win32.zip"解压到D:\LUA_TOOL
目标:为了实现C++调用LUA脚本时,该脚本能进行实时仿真
注意:本文会用到我上一篇"window QT/C++ 与 lua交互(mingw + lua + LuaBridge + luasocket)"生成的库,如果有需要可以看我上一篇
链接
二、LUA脚本与qt/c++项目
1、编写LUA脚本
1)这次我们就实现一个,qt/c++程序调用A脚本,然后A脚本又调用B脚本,这个B脚本是被放在一个名为"base"的文件夹下。
我这里就还是跟上一篇一样,将我的lua都放在'D:\LUA_TOOL\my_lua'下
2)A.lua
lua
-- package.path 和 package.cpath很重要,一个是寻找lua脚本的目录,一个是寻找dll的目录
-- 定义变量保存路径
local LuaSocketPath = 'D:\\LUA_TOOL\\luasocket_mingw_DLL'
local zeroBranePath = 'D:\\LUA_TOOL\\ZeroBraneStudioEduPack-2.01-win32'
local basePath = 'D:\\LUA_TOOL\\my_lua'
-- 设置 Lua 库路径
package.path = LuaSocketPath .. '\\?.lua;.\\?.lua;' ..
basePath .. '\\?.lua;' ..
zeroBranePath .. '\\lualibs\\?\\?.lua;' ..
zeroBranePath .. '\\lualibs\\?.lua;'
package.cpath = LuaSocketPath .. '\\?.dll;' ..
zeroBranePath .. '\\bin\\clibs54\\?.dll;' ..
zeroBranePath .. '\\bin\\?.dll;' ..
zeroBranePath .. '\\bin\\clibs\\?.dll'
--这里是调用B.lua
require("base/B")
-- 加载调试库
local tDebug = require('mobdebug')
-- 启动ZeroBraneStudio调试服务器
tDebug.start()
function my_func()--这个函数将被C++调用
local ret=my_add(1,5)--调用B.lua里面的my_add函数
print("hello1 my_func")
print(ret)
tDebug.done()--退出ZeroBraneStudio调试服务器,释放资源,这里很重要,一定要释放!!!
return 0;
end
关于上面路径的解释:
LuaSocketPath 是我上一篇文章编译好的dll路径
zeroBranePath 是刚才解压ZeroBraneStudioEduPack-2.01-win32的路径。这里一定要填对,不然后面仿真的时候会无法调试,而且我们也需要用到ZeroBraneStudio里面的lua和dll
basePath 是用于查找依赖文件的,像B.lua就是依赖文件,如果这里不填对,zeroBranePath 就没办法找到B.lua。
3)B.lua
lua
function my_add (a,b)
c=a+b
return c;
end
2、QT TEST_LUA项目
1、这个TEST_LUA项目是我在上一篇文章就建好的,这里就不再重复如何去构建,需要了解的小伙伴请看上一篇
2、我们需要用这个建好的TEST_LUA项目来调用刚才的A.lua里面的my_func函数
mainwoindow.h
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "common_lua.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
lua_State * L;
};
#endif // MAINWINDOW_H
mainwoindow.c
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
L = luaL_newstate(); //新建lua解释器
luaL_openlibs(L); //载入lua基础库
//执行lua脚本
//载入lua脚本
if (luaL_dofile(L, "D:\\LUA_TOOL\\my_lua\\A.lua")) {
qDebug() << "Error loading script: " << lua_tostring(L, -1) ;
lua_pop(L, 1);
}
else {
qDebug() << "executeScriptFile OK" ;
}
// 调用 Lua 函数 my_func
lua_getglobal(L, "my_func");
if (lua_pcall(L, 0, 0, 0) != 0) {
qDebug() << "Error running function 'my_func': " << lua_tostring(L, -1);
lua_pop(L, 1);
}
lua_close(L);
}
注意:这里重点说一下luaL_dofile(L, "D:\LUA_TOOL\my_lua\A.lua"),里面的路径一定要是绝对路径,不然在ZeroBraneStudio连接后会报错
ZeroBraneStudio报错:
Debugging suspended at 'A.lua:34'(couldn't activate the file).
二、ZeroBraneStudio仿真
1、打开ZeroBraneStudio
2、选择LUA编译器版本,我项目用的是lua5.3.5的源码,所以选的是5.3。(各位根据实际来)
3、启动远程调试,这一步很重要,不然就连不上!
4、打开A.lua和B.lua(自己要仿真/调试几个lua就打开几个)
5、在A.lua和B.lua分别打上断点(我这里为了实验就随便打的)
5、编译TEST_LUA项目,点击button,然后进入ZeroBraneStudio仿真
6、仿真效果