C++ 和lua交互学习的三个例子
来源:互联网 发布:java堆栈图解 编辑:程序博客网 时间:2024/06/15 18:10
C++ 和 Lua 交互学习
Lua简介及安装
Lua的优点:
- 最快的脚本语言
- 可以编译调试
- 与C/C++结合容易
- Lua是对性能有要求的必备语言
Lua的应用:
- 游戏的任务脚本,后端服务器
- AlphaGo: C++ + lua实现
- 视频服务器、入侵检测脚本、防火墙脚本
Lua的官网: http://www.lua.org/versions.html
- 5.1 较快
- 5.3 性能有些下降
Lua的安装
C++ 调用 lua之前需要先安装lua,可以下载lua的源码进行编译安装,在CentOS平台下,还可以直接使用yum安装,CentOS默认使用lua的版本是5.1的版本,如:
yum install lua lua-devel
Lua 的基本概念
Lua的基本数据类型:
- nil:表示没有数据,当希望释放数据时,直接将nil赋值给该变量即可
- boolean:在lua中除了false和nil为假,其他都为真,true|false
- numbers类型:
- lua中没有整数,都是浮点数运算,对应C中的double;
- 新版本的lua是基于64位的整型,5.1暂不支持
- 可以tonumber转换格式
- string类型:
- tostring转换格式
- [[]]多行字符串赋值
- 与C一样的转义
- 通过..实现字符串的拼接,且可以直接拼接整型,注意不能拼接nil的变量
- string.len(str), 获取字符串长度
- string.sub(str,3,5),获取子字符串
- local b,e = string.find(),查找,支持正则
- string.gsub(),替换,不改变原值,返回替换后的值,支持正则
- lua的下标是从1开始的,和matlab相同
Lua和C++的交互
调用C++中的函数, 通过堆栈交互
包含头文件
extern "C" {#include <lua.h> #include <lualib.h> #include <lauxlib.h> }
编译
g++ -o XX XX.cpp -llua -ldl
第一个例子
C++代码
#include <iostream> using namespace std;extern "C" {#include <lua.h> #include <lualib.h> #include <lauxlib.h> }int main(){ lua_State *L = lua_open(); luaopen_base(L); luaopen_string(L); luaopen_table(L); // 加载 lua 文件 if ( luaL_loadfile(L, "main.lua") ) { const char* error = lua_tostring(L, -1); cout << "lua load error: "<< error << endl; return -1; } // 执行 lua 文件 if ( lua_pcall(L, 0, 0, 0) ) { const char* error = lua_tostring(L, -1); cout << "lua call error: "<< error << endl; return -1; } getchar(); return 0;}
lua代码
print("hello word")
第二个列子
C++ code
#include <iostream>using namespace std;extern "C"{#include <lua.h>#include <lualib.h>#include <lauxlib.h>}// 开放函数给lua调用,并获取 Lua 传递的三个参数,普通参数int CTest(lua_State* L){ cout << "enter in CTest" << endl; size_t len; const char* name = lua_tolstring(L, 1, &len); cout << "Lua name: " << name << endl; int age = lua_tonumber(L, 2); cout << "Lua age: " << age << endl; bool bIs = lua_toboolean(L, 3); cout << "Lua bool: " << bIs << endl; return 0;}// 开放函数给lua调用,并获取 Lua 传递的表参数,按索引获取表参数int CTestArray(lua_State* L){ cout << "In CTestArray" << endl; int arrLen = luaL_getn(L,1); // 获取表的长度 cout << "Table size: " << arrLen << endl; for (int i = 1; i <= arrLen; i++) { lua_pushnumber(L, i); // 2 lua_gettable(L,1); // pop index and push table[i] size_t iSize = 0; cout << lua_tolstring(L, -1, &iSize) << endl; lua_pop(L, 1); } return 0;}// 开放函数给lua调用,并获取 Lua 传递的表参数,按键值获取表参数int CTestKeyVal(lua_State* L){ cout << "In CTestKeyVal" << endl; lua_pushnil(L); while(lua_next(L,1) != 0) { cout << "key=" << lua_tostring(L,2) << ", "; cout << "value=" << lua_tostring(L,-1) << endl; lua_pop(L,1); } return 0;}// 开放函数给lua调用,并判断获取的参数是否是希望的类型int CTestKeyVal_type(lua_State* L){ // method1: type check luaL_checktype(L, 1, LUA_TTABLE); // method2: type check if (lua_type(L,2) != LUA_TNUMBER) { cout << "para 2 is not a number" << endl; } cout << "In CTestKeyVal" << endl; lua_getfield(L,1, "name"); cout << "name: " <<lua_tostring(L,-1) <<endl; return 0;}// 开放函数给lua调用,C++ 返回一个普通的字符串int CTestRetOne(lua_State* L){ lua_pushstring(L, "return a string value"); return 1;}// 开放函数给lua调用,C++ 返回一个表int CTestRetTable(lua_State* L){ lua_newtable(L); // create new table lua_pushstring(L, "name"); // push key lua_pushstring(L, "xiaominmin");// pusn value lua_settable(L, -3);// write key and value into table lua_pushstring(L, "age"); lua_pushnumber(L, 29); lua_settable(L, -3); return 1;}int main(){ lua_State *L = lua_open(); luaopen_base(L); luaopen_string(L); luaopen_table(L); // 注册开发的函数给lua lua_register(L, "CTest", CTest); lua_register(L, "CTestArray", CTestArray); lua_register(L, "CTestKeyVal", CTestKeyVal); lua_register(L, "CTestKeyVal_type", CTestKeyVal_type); lua_register(L, "CTestRetOne", CTestRetOne); lua_register(L, "CTestRetTable", CTestRetTable); if ( luaL_loadfile(L, "main.lua") ) { const char* error = lua_tostring(L, -1); cout << "lua load error: "<< error << endl; return -1; } if ( lua_pcall(L, 0, 0, 0) ) { const char* error = lua_tostring(L, -1); cout << "lua call error: "<< error << endl; return -1; } getchar(); return 0;}
lua code
-- 调用 CTest,并传递三个普通参数CTest("Lua string",123, true)-- 调用CTestArray,并传递带索引的表local arr = {"A001","A002","A003", "A004"}CTestArray(arr)-- 调用 CTestKey,并传递键值表local arr = {name="xiaoming", age="32",id="007"}local size = "s108"CTestKeyVal(arr)-- 调用 CTestKey_type,并传递键值表,判读参数类型是否是期望的类型local arr = {name="xiaoming", age="32",id="007"}local size = "s108"CTestKeyVal_type(arr, size)-- 调用 CTestRetOne,并打印C++返回的值local ret = CTestRetOne()print ("ret = "..ret)-- 调用 CTestRetTable,并打印C++的表local ret = CTestRetTable()print ("name = "..ret["name"])print ("age = "..ret["age"])
第三个例子
C++ code
#include <iostream>using namespace std;extern "C"{#include <lua.h>#include <lualib.h>#include <lauxlib.h>} int main(){ lua_State *L = lua_open(); // 打开需要用到的lua的库 luaopen_base(L); luaopen_string(L); luaopen_table(L); /* lua脚本启动之前,给lua脚本设置全局变量 */ // 设置lua的全局变量,hello = test (key = value) lua_pushstring(L, "hello"); lua_setglobal(L,"test"); // 向 lua 中传递一个表,同例子2中的返回一个表给lua lua_newtable(L); // create a table lua_pushstring(L, "name"); // key lua_pushstring(L, "xiaoming"); // value lua_settable(L, -3); lua_pushstring(L, "age"); // key lua_pushnumber(L, 20); // value lua_settable(L, -3); lua_setglobal(L, "person"); // write value to table if ( luaL_loadfile(L, "main.lua") ) { const char* error = lua_tostring(L, -1); cout << "lua load error: "<< error << endl; return -1; } if ( lua_pcall(L, 0, 0, 0) ) { const char* error = lua_tostring(L, -1); cout << "lua call error: "<< error << endl; return -1; } // C++ 获取lua中的普通全局变量 lua_getglobal(L, "width"); int width = lua_tonumber(L, -1); lua_pop(L, 1); // 注意要清lua堆栈 cout << "width: " << width << endl; // C++ 获取lua中的表全局变量 lua_getglobal(L, "conf"); lua_getfield(L, -1, "titlename"); cout << "titlename: " << lua_tostring(L,-1) << endl; lua_pop(L,1); lua_getfield(L, -1, "height"); cout << "height: " << lua_tonumber(L, -1) << endl; lua_pop(L, 1); // C++ 调用 lua中的名为 event的函数,无参数无返回值 cout<< "stack top is " << lua_gettop(L) << endl; lua_getglobal(L, "event"); if ( lua_pcall(L, 0, 0, 0) != 0)// 无参数,无返回值,无回调函数 { cout << "call event failed " << lua_tostring(L, -1)<< endl; lua_pop(L, 1); } cout<< "stack top is " << lua_gettop(L) << endl; // C++ 调用 lua中的名为 ferror和event2 的函数,有参数有返回值 cout<< "stack top is " << lua_gettop(L) << endl; int errfun = lua_gettop(L); lua_getglobal(L, "ferror"); errfun++; lua_getglobal(L, "event2"); lua_pushstring(L, "key"); if ( lua_pcall(L, 1, 1, errfun) != 0)// 一个参数,一个返回值,回调函数errfun { cout << "call event failed " << lua_tostring(L, -1)<< endl; lua_pop(L, 1); } else { cout << "Lua return: " << lua_tostring(L, -1) << endl; lua_pop(L, 1); } lua_pop(L, 1); cout<< "stack top is " << lua_gettop(L) << endl; // C++ 调用 lua中的名为 ferror和event3 的函数,有表参数和表返回值 cout<< "stack top is " << lua_gettop(L) << endl; int errfun1 = lua_gettop(L); lua_getglobal(L, "ferror"); errfun1++; lua_getglobal(L, "event3"); lua_pushstring(L, "key"); lua_newtable(L); lua_pushstring(L,"name"); lua_pushstring(L, "xiaomingming"); lua_settable(L, -3); if ( lua_pcall(L, 2, 1, errfun) != 0) // 两个参数,一个返回值,回调函数errfun { cout << "call event failed " << lua_tostring(L, -1)<< endl; lua_pop(L, 1); } else { //cout << "Lua return: " << lua_tostring(L, -1) << endl; lua_getfield(L, -1, "id"); cout << "Lua return id: " << lua_tonumber(L, -1) << endl; lua_pop(L,1); lua_getfield(L, -1, "age"); cout << "lua return age: " << lua_tonumber(L, -1) << endl; lua_pop(L, 1); lua_pop(L, 1); } lua_pop(L, 1); cout<< "stack top is " << lua_gettop(L) << endl; lua_close(L); return 0;}
lua code
-- Lua的全局变量,供C++使用width=1920conf = { titlename = "first lua", height = 1080}-- 打印C++设置的全局变量,普通变量print("C++ test: ".. test)-- 打印C++设置的全局变量,表for k,v in pairs(person) do print(k.."=>"..v)end-- C++ 调用 lua函数并传递普通参数,lua函数有返回值function ferror(e) print("lua error: "..e) return "lua change error"end-- C++ 调用 lua函数,无参数,lua函数无返回值function event() print("C++ call lua function.") end-- C++ 调用 lua函数并传递普通参数,lua函数有返回值function event2(e) print("C++ call lua function event 1.") print(e) return "Lua renturn a string"end-- C++ 调用 lua函数并传递表参数,lua函数返回表参数function event3(e, obj) print("C++ call lua function event 1.") print(e) print (obj.name) local re = {id=123, age=29} return reend
0 0
- C++ 和lua交互学习的三个例子
- 通过例子学习Lua(5)--Lua与C的交互
- 通过例子学习Lua(5) ---- Lua与C交互入门
- lua和c的交互
- lua和c的交互
- lua和c的交互
- lua和c的交互
- lua和c的交互
- lua和c的交互
- lua和c的交互
- lua和c的交互
- lua和c的交互
- lua和c的交互
- lua和c的交互
- C和lua交互
- lua和C交互
- Lua学习---c和lua的交互之表的操作
- C/C++和Lua的交互
- (27)表插入排序
- 选择小波的实验方法,自己查看
- 【工作记录】maven本地仓库和远程仓库的理解
- GIT的深入理解与使用
- Uboot预备知识
- C++ 和lua交互学习的三个例子
- (c语言)在一个有数字的字符串中输出最长的数字
- PRML读书笔记——线性回归模型
- c++运算符重载的方法提要
- 选项卡控制器(tabBarController)基础
- 写给初学者22_android_百分比布局
- 二分图的最大匹配——匈牙利算法
- 【面试题】剑指Offer-50-求两个节点的最近公共祖先
- 二叉树的基本操作(严蔚敏)