1.前言
Lua作为一个运行效率非常高的脚本语言,简单方便,如今很多游戏开发都会用到.今天研究下c++和lua是如何交互的~
2.c++调用lua
我是在macos上实验的,过程应该和linux上类似.使用的lua版本是5.3.0.
c++调用lua原理主要是通过Lua的堆栈,一方将传递的参数以及参数个数压入栈中,另一方则在栈中取出参数,并将返回值压入栈中,由另一方取出,实现交互.这个过程和c++和汇编(如nasm)的交互过程很像.
(i).添加依赖
将liblua.a添加到项目中:
![lib](https://Nirvana1997.github.io//2018/08/22/lua与c-的交互/lib.png)
设置search paths:
Header Search Paths设置为lua安装位置,用来搜索头文件.
Library Search Paths设置为项目存放.a库的目录.
![lib](https://Nirvana1997.github.io//2018/08/22/lua与c-的交互/path.png)
(ii).代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" }
using namespace std;
int () { lua_State *L = luaL_newstate(); lua_pushstring(L, "Hello World~"); if (lua_isstring(L, 1)) { cout << lua_tostring(L, 1) << endl; } lua_close(L); }
|
(iii).运行代码
运行结果:
![lib](https://Nirvana1997.github.io//2018/08/22/lua与c-的交互/run.png)
(iv).求和代码:
lua代码:
1 2 3
| function Sum(a, b) return (a+b); end
|
c++代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" }
using namespace std;
int () { lua_State *L = luaL_newstate(); if (L == NULL) { return 0; } int bRet = luaL_loadfile(L, "sum.lua"); if (bRet) { cout << "load file error" << endl; return 0; } bRet = lua_pcall(L, 0, 0, 0); if (bRet) { cout << "pcall error" << endl; return 0; } lua_getglobal(L, "Sum"); lua_pushinteger(L, 10); lua_pushinteger(L, 8); int iRet = lua_pcall(L, 2, 1, 0); if (iRet) { const char *pErrorMsg = lua_tostring(L, -1); cout << pErrorMsg << endl; lua_close(L); return 0; } if (lua_isinteger(L, -1)) { int sum = lua_tointeger(L, -1); cout << sum << endl; } lua_close(L); return 0; }
|
结果:
![sum](https://Nirvana1997.github.io//2018/08/22/lua与c-的交互/sum.png)
3.lua调用c++
lua调用c++原理主要是将c++代码编译成.so动态库,然后在lua中用require引入,从而调用.通信还是通过lua栈来实现的.这里就不展开了.具体可以参考lua官方文档,还有lua5.3中文文档
4.LuaTinker
以上介绍的都是lua官方的提供给c的一些api,较为底层,其实有很多c++和lua代码的绑定库,将以上的栈操作以及函数注册等封装了起来,如LuaBind,LuaTinker等,我们的项目中使用的就是LuaTinker.LuaTinker使用方法可以在git仓库中查看.