在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
0. 前言
配置QT工程文件 LuaDemo.pro 两个注意点,注意lua版本间的差异。还有就是SOURCES += 加入C文件时, lua.c luac.c 这两个文件不要加入到编译文件中。下面这个pro工程文件,仅供参考 1 QT += core gui 2 3 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 4 5 CONFIG += c++11 6 7 # The following define makes your compiler emit warnings if you use 8 # any Qt feature that has been marked deprecated (the exact warnings 9 # depend on your compiler). Please consult the documentation of the 10 # deprecated API in order to know how to port your code away from it. 11 DEFINES += QT_DEPRECATED_WARNINGS 12 13 # You can also make your code fail to compile if it uses deprecated APIs. 14 # In order to do so, uncomment the following line. 15 # You can also select to disable deprecated APIs only up to a certain version of Qt. 16 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 17 18 SOURCES += \ 19 lua-5.3.5/src/lapi.c \ 20 lua-5.3.5/src/lauxlib.c \ 21 lua-5.3.5/src/lbaselib.c\ 22 lua-5.3.5/src/lbitlib.c \ 23 lua-5.3.5/src/lcode.c \ 24 lua-5.3.5/src/lcorolib.c\ 25 lua-5.3.5/src/lctype.c \ 26 lua-5.3.5/src/ldblib.c \ 27 lua-5.3.5/src/ldebug.c \ 28 lua-5.3.5/src/ldo.c \ 29 lua-5.3.5/src/ldump.c \ 30 lua-5.3.5/src/lfunc.c \ 31 lua-5.3.5/src/lgc.c \ 32 lua-5.3.5/src/linit.c \ 33 lua-5.3.5/src/liolib.c \ 34 lua-5.3.5/src/llex.c \ 35 lua-5.3.5/src/lmathlib.c\ 36 lua-5.3.5/src/lmem.c \ 37 lua-5.3.5/src/loadlib.c \ 38 lua-5.3.5/src/lobject.c \ 39 lua-5.3.5/src/lopcodes.c\ 40 lua-5.3.5/src/loslib.c \ 41 lua-5.3.5/src/lparser.c \ 42 lua-5.3.5/src/lstate.c \ 43 lua-5.3.5/src/lstring.c \ 44 lua-5.3.5/src/lstrlib.c \ 45 lua-5.3.5/src/ltable.c \ 46 lua-5.3.5/src/ltablib.c \ 47 lua-5.3.5/src/ltm.c \ 48 lua-5.3.5/src/lundump.c \ 49 lua-5.3.5/src/lutf8lib.c\ 50 lua-5.3.5/src/lvm.c \ 51 lua-5.3.5/src/lzio.c \ 52 main.cpp \ 53 mainwindow.cpp \ 54 qtwidgetbridgelua.cpp 55 56 57 58 HEADERS += \ 59 common.h \ 60 mainwindow.h \ 61 qtwidgetbridgelua.h 62 63 #INCLUDEPATH += lua-5.2.0/src 64 INCLUDEPATH += lua-5.3.5/src 65 66 67 FORMS += \ 68 mainwindow.ui 69 70 # Default rules for deployment. 71 qnx: target.path = /tmp/$${TARGET}/bin 72 else: unix:!android: target.path = /opt/$${TARGET}/bin 73 !isEmpty(target.path): INSTALLS += target 头文件引用 common.h 这里引用lua.hpp, 还有LuaBridge.h 即可。 1 #ifndef COMMON_H 2 #define COMMON_H 3 4 #include "lua.hpp" 5 #include "LuaBridge/LuaBridge.h" 6 7 #include <QString> 8 #include <QRandomGenerator> 9 #include <QDebug> 10 11 12 #endif // COMMON_H 这样就把lua和LuaBridge依赖关系搞定了。接下来就是写逻辑代码了。
QT调用Lua,相对比较简单。 1 lua_State * LUA; 2 int luaAdd(int x, int y) 3 { 4 int sum; 5 lua_getglobal(LUA, "add"); 6 lua_pushnumber(LUA, x); 7 lua_pushnumber(LUA, y); 8 lua_call(LUA, 2, 1); //2个参数, 1个返回值 9 sum = (int)lua_tonumber(LUA, -1); //获取结果 10 lua_pop(LUA, 1); //清楚返回值,弹出栈 11 return sum; 12 } 13 14 int main(int argc, char *argv[]) 15 { 16 LUA = luaL_newstate(); //新建lua解释器 17 luaL_openlibs(LUA); //载入lua基础库 18 //执行lua脚本 19 //luaL_loadfile(LUA, "add.lua"); //载入lua脚本 20 luaL_dofile(LUA, "add.lua"); 21 int sum = luaAdd(10, 20); 22 qDebug() << "sum: " << sum; 23 lua_close(LUA); 24 return 0; 25 }
3. Lua调用QT 定义几个Class 1 class A 2 { 3 public: 4 A() { } 5 virtual void foo( int a ) { 6 qDebug() << "foo base: " << a << ":" << Member.c_str(); 7 } 8 std::string Member; 9 }; 10 11 class B : public A 12 { 13 public: 14 virtual void foo( int a ) { 15 qDebug() << "foo inherited: " << a << ":" << Member.c_str(); 16 } 17 }; 18 void foo(int a) { 19 qDebug() << "foo: " << a; 20 } 1 class A; class B; 2 lua_State * LUA; 3 int main(int argc, char *argv[]) 4 { 5 qDebug() << "aab"; 6 lua_State* L = luaL_newstate(); 7 //加载Lua基本库 8 luaL_openlibs(L); 9 luabridge::getGlobalNamespace(L) 10 .beginClass<A>("Sobj") 11 .addConstructor<void (*) (void)> () 12 .addFunction("foo", &A::foo) 13 .addData("Member",&A::Member) 14 .endClass() 15 .deriveClass<B, A>("SSec") 16 .addFunction("foo",&B::foo ) 17 .endClass(); 18 luabridge::getGlobalNamespace(L).addFunction("foo", foo ); 19 20 B ins; 21 ins.Member = "data"; 22 luabridge::setGlobal(L, ins, "ins"); 23 ins.foo(3); 24 25 luaL_dofile(L, "qt.lua"); 26 return 0; 27 } Lua脚本 1 print('start') 2 local a = Sobj() 3 a.Member='World' 4 a:foo(2) 5 ins.Member='Hello' 6 ins:foo(3) 7 foo(1) 8 print('end')
4. 代码预览 common.h 1 #ifndef COMMON_H 2 #define COMMON_H 3 4 #include "lua.hpp" 5 #include "LuaBridge/LuaBridge.h" 6 7 #include <QString> 8 #include <QRandomGenerator> 9 #include <QDebug> 10 11 12 #endif // COMMON_H mainwindow.h 1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include "qtwidgetbridgelua.h" 5 #include <QMainWindow> 6 7 QT_BEGIN_NAMESPACE 8 namespace Ui { class MainWindow; } 9 QT_END_NAMESPACE 10 11 class MainWindow : public QMainWindow 12 { 13 Q_OBJECT 14 15 public: 16 MainWindow(QWidget *parent = nullptr); 17 ~MainWindow(); 18 19 private slots: 20 void on_btnQtCallLua_clicked(); 21 void on_btnLuaCallQt_clicked(); 22 23 private: 24 Ui::MainWindow *ui; 25 QtWidgetBridgeLua lua; 26 }; 27 #endif // MAINWINDOW_H qtwidgetbridgelua.h 1 #ifndef QTWIDGETBRIDGELUA_H 2 #define QTWIDGETBRIDGELUA_H 3 4 #include "common.h" 5 6 class QtWidgetBridgeLua 7 { 8 public: 9 QtWidgetBridgeLua(); 10 ~QtWidgetBridgeLua(); 11 12 //加载Lua调Qt的脚本 13 void luaCallQtLoadCode(QString code); 14 //注册所有函数 15 void registerFunction(); 16 //加法 17 int luaCallQtAdd(int x, int y); 18 //计算字符长度 19 int luaCallQtStrlen(std::string str); 20 //产生随机数 21 std::string luaCallQtRandomStr(int cnt); 22 //打印变量 23 void luaCallQtPrint(); 24 25 //加载Qt调用Lua的脚本 26 void qtCallLuaLoadCode(QString code); 27 //加法 28 int qtCallLuaAdd(int x, int y); 29 //计算字符长度 30 int qtCallLuaStrlen(std::string str); 31 //产生随机数 32 std::string qtCallLuaRandomStr(int cnt); 33 //打印变量 34 void qtCallLuaPrint(); 35 36 public: 37 std::string member; 38 int value; 39 40 private: 41 lua_State * L; 42 }; 43 44 #endif // QTWIDGETBRIDGELUA_H main.cpp 1 #include "mainwindow.h" 2 #include "qtwidgetbridgelua.h" 3 4 #include <QApplication> 5 #include <QDebug> 6 7 //#include "lua.hpp" 8 //#include "LuaBridge/LuaBridge.h" 9 10 int main(int argc, char *argv[]) 11 { 12 QApplication a(argc, argv); 13 MainWindow w; 14 w.show(); 15 return a.exec(); 16 } mainwindow.cpp 1 #include "mainwindow.h" 2 #include "ui_mainwindow.h" 3 4 MainWindow::MainWindow(QWidget *parent) 5 : QMainWindow(parent) 6 , ui(new Ui::MainWindow) 7 { 8 ui->setupUi(this); 9 10 } 11 12 MainWindow::~MainWindow() 13 { 14 delete ui; 15 } 16 17 void MainWindow::on_btnQtCallLua_clicked() 18 { 19 QString txt = ui->txtQtCallLua->toPlainText(); 20 lua.qtCallLuaLoadCode(txt); 21 qDebug() << "qt call lua:"; 22 //调用加法计算 23 int sum = lua.qtCallLuaAdd(20, 30); 24 qDebug() << "add :" << sum; 25 //调用计算字符串长度 26 int len = lua.qtCallLuaStrlen("Hello World!!"); 27 qDebug() << "strlen: " << len; 28 //调用随机数 29 std::string randstr = lua.qtCallLuaRandomStr(12); 30 qDebug() << "randstr: " << randstr.c_str(); 31 //调用打印 32 lua.qtCallLuaPrint(); 33 } 34 35 void MainWindow::on_btnLuaCallQt_clicked() 36 { 37 QString txt = ui->txtLuaCallQt->toPlainText(); 38 lua.luaCallQtLoadCode(txt); 39 } qtwidgetbridgelua.cpp 1 #include "qtwidgetbridgelua.h" 2 3 QtWidgetBridgeLua::QtWidgetBridgeLua() 4 { 5 L = luaL_newstate(); //新建lua解析器 6 luaL_openlibs(L); //载入lua基础库 7 } 8 QtWidgetBridgeLua::~QtWidgetBridgeLua() 9 { 10 lua_close(L); //释放lua解析器 11 } 12 13 /****************Lua调用Qt函数*******************/ 14 void QtWidgetBridgeLua::luaCallQtLoadCode(QString code) 15 { 16 //每次都重新创建lua解析器 17 lua_close(L); 18 L = luaL_newstate(); 19 luaL_openlibs(L); 20 //注册所有函数 21 registerFunction(); 22 luaL_dostring(L, code.toStdString().c_str()); //加载脚本 23 //luaL_dofile(L, "sample.lua"); //文件方式加载脚本 24 } 25 void QtWidgetBridgeLua::registerFunction() 26 { 27 luabridge::getGlobalNamespace(L) 28 .beginClass<QtWidgetBridgeLua>("QtUtils") 29 .addConstructor<void (*) (void)>() 30 .addFunction("luaCallQtAdd", &QtWidgetBridgeLua::luaCallQtAdd) 31 .addFunction("luaCallQtStrlen", &QtWidgetBridgeLua::luaCallQtStrlen) 32 .addFunction("luaCallQtRandomStr", &QtWidgetBridgeLua::luaCallQtRandomStr) 33 .addFunction("luaCallQtPrint", &QtWidgetBridgeLua::luaCallQtPrint) 34 .addData("member", &QtWidgetBridgeLua::member) 35 .addData("value", &QtWidgetBridgeLua::value) 36 .endClass(); 37 } 38 int QtWidgetBridgeLua::luaCallQtAdd(int x, int y) 39 { 40 return x + y; 41 } 42 int QtWidgetBridgeLua::luaCallQtStrlen(std::string str) 43 { 44 return str.length(); 45 } 46 std::string QtWidgetBridgeLua::luaCallQtRandomStr(int cnt) 47 { 48 const char ch[] = "0123456789abcdefABCDEF"; 49 int start = 0; 50 int end = sizeof(ch) - 1; 51 char *str = new char[cnt + 1]; 52 for(int i=0; i<cnt; i++) 53 { 54 int val = QRandomGenerator::global()->bounded(start, end); 55 str[i] = ch[val]; 56 } 57 str[cnt] = '\0'; 58 return std::string(str); 59 } 60 void QtWidgetBridgeLua::luaCallQtPrint() 61 { 62 qDebug() << this->member.c_str() << " : " << this->value; 63 } 64 65 /****************Qt调用Lua函数*******************/ 66 void QtWidgetBridgeLua::qtCallLuaLoadCode(QString code) 67 { 68 //每次都重新创建lua解析器 69 lua_close(L); 70 L = luaL_newstate(); 71 luaL_openlibs(L); 72 73 luaL_dostring(L, code.toStdString().c_str()); //加载脚本 74 //luaL_dofile(L, "sample.lua"); //文件方式加载脚本 75 } |
请发表评论