本来这些文章都是在我的个人网站www.zhangyi.studio,目前处在备案状态,暂时访问不了,所以搬到这边。
最近这两天需要弄清楚C++和lua间相互调用和数据传递,废话不多说,直接上过程。
1 首先是环境环境,Linux(Debian),安装lua,注意需要管理员权限。
sudo apt-get install lua5.2
安装完后输入lua或者lua -v 严重是否安装成功以及安装的版本,当然,有了lua运行环境还不够我们还需要安装lua开发库既然我们安装的是lua5.2那么开发库同样安装成5.2版本,命令如下:
sudo apt-get install liblua5.2-dev
当然,lua的环境准备好了,既然要研究lua和C/C++的交互,那gcc/g++是必不可少的,至于怎么安装,此处略过,默认认为已安装好。
接下来就得写代码验证一下
因为lua是一种解释性语言,它不不同于C/C++,且两者之间不能直接做数据交互,需要一种类似于“栈”的结构来实现数据交互,规定是:C/C++有C/C++的环境,lua有lua的环境,两张互不干扰,如需交互数据,双方都要把数据放入“栈”中;并且lua和C/C++的数据类型也不相同,所以不能直接从栈中拿来使用。以下说明一种最典型的lua数据类型-table,如下:
1 //Data.lua 2 Data = 3 { 4 name = "zhang_yi" , 5 age = 24 , 6 homepage = "zhangyi.studio" , 7 lover = "lijuanxian" , 8 }
假设我现在要用当前文件Data.lua中读取某个元素,例如name元素,一般有如下几个步骤:
1 //创建luaState 2 lua_State *L = luaL_newstate(); 3 4 //加载lua文件,dofile是加载并执行文件,结果是生成全局table 5 luaL_dofile(L ,"Data.lua"); 6 7 //将我们需要处理的table置于栈顶,此时全局变量Data的index为-1(栈顶) 8 lua_getglobal(L, "Data"); 9 10 //将我们需要读取的元素索引压栈,此时Data的index为-2,"name"的index为-1 11 lua_pushstring(L, "name"); 12 //调用查找接口,过程:用栈顶元素作为索引在table中查找对应得元素,如果查到 13 //POP索引(此处为"name"),把结果放到栈顶(查到的值返回到栈顶,index =-1) 14 lua_gettable(L, -2); 15 16 //读取查到的结果,当然,需要先做类型判断 17 lua_isstring(L, -1) 18 string str = lua_tostring(L, -1); 19 20 //至此,我们便从lua脚本的table中取得了我们想要的元素。 21 //当然最后别忘了销毁现场 22 lua_close(L);
全部源码如下:
①、Data.lua
1 --Data.lua 2 Data = 3 { 4 name = "zhang_yi" , 5 age = 24 , 6 homepage = "zhangyi.studio" , 7 lover = "lijuanxian" , 8 }
②、cUseLua.cpp
1 //cUseLua 2 #include <iostream> 3 #include <string.h> 4 #include "mylua.h" 5 6 using namespace std; 7 8 int main() 9 { 10 lua_State *L = luaL_newstate(); 11 if(L == NULL) 12 { 13 cout<<"Creat Lua State Error !"<<endl; 14 return 1; 15 } 16 int ret = luaL_dofile(L ,"Data.lua"); 17 if(ret) 18 { 19 cout<<"Lua doFile Error !"<<endl; 20 return 1; 21 } 22 lua_getglobal(L, "Data"); 23 lua_pushstring(L, "name"); 24 lua_gettable(L, -2); 25 if(lua_isstring(L, -1)) 26 { 27 string str = lua_tostring(L, -1); 28 cout<<str<<endl; 29 } 30 31 lua_close(L); 32 return 0 ; 33 }
③、mylua.h
1 //mylua.h 2 #ifndef MYLUA_H_ 3 #define MYLUA_H_ 4 5 extern "C" 6 { 7 #include<lua5.2/lua.h> 8 #include<lua5.2/lauxlib.h> 9 #include<lua5.2/lualib.h> 10 } 11 #endif
最后,编译运行
g++ -o Main main.cpp -llua5.2
通过table交互数据的目的达到了,接下来就是C/C++调用写在lua中的函数以及lua脚本调用C/C++接口因为lua作为一种轻量级的解释性语言,不需要编译链接等步骤,所以作为C/C++内嵌语言非常合适,我们在
项目研发过程中特别希望程序能经常不变,或者说不经常改动,再此,更加体现出类似于lua这种解释性语言的魅力,一些需要经常变动的接口或者逻辑用lua来写,然后让主程序(C、C++)通过固定的接口来调用,这样
便可以达到目的。