版权声明:本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名elloop(包含链接)
自从13年开始做手游接触lua,始终是边写边学,缺乏对lua更加全面系统的学习,这几篇文章开始“重识lua”, 把欠下的帐还回来。这个系列侧重于总结lua作为扩展程序的用法,不会着重介绍lua的语法。
前言
本文介绍如何在C++中调用lua的function,lua很多情况下是被用做一种扩展语言,它的function更是增加了这门扩展语言的灵活性,赋予了lua生命力,使它变化莫测。在lua的function中还可以回调宿主语言的函数。这篇文章展示如何从C++端调用lua函数,相反的过程在后面的文章再做介绍。
本文使用的Lua版本还是5.1。
简单的调用示例
还是使用上一篇文章中使用的环境,调用config.lua里面的f函数:
res/config.lua:
main.cpp:
lua_pcall
其实这个例子里面出现的几个API在前两篇文章中都已经见过,只不过没有用来调用function。这里面调用function的API就是lua_pcall
, 它的原型是:
LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
第一个参数是lua状态,第二个参数是输入参数个数,第三个参数是返回值个数,最后一个参数是错误处理函数.
注意:无论在执行正常还是出错,之前在栈中的函数和输入参数都会被弹出;如果调用失败,会压入一条错误信息;如果调用成功, `lua_pcall`先弹出函数和输入参数,然后压入返回值,如果返回值个数多于指定的返回值个数nresults, 那么多余的会被丢弃;如果小于nresults,则会压入nil来凑数。
关于错误处理函数
在上面的例子中,没有使用错误处理函数,lua_pcall
的第四个参数传入0即表示不设置错误处理函数。注意到这个参数是一个整数,它的含义是错误处理函数在虚拟栈中的索引。因此,如果我想指定错误处理函数,那么要在调用函数之前,把错误处理函数先压入栈, 而且要先于函数和其参数。当lua_pcall
调用失败,在压入错误信息之前,会先调用这个错误处理函数。
lua_pcall
的返回值
有没有与lua_pcall
类似的调用函数?
封装调用函数
在PIL第25.4节,介绍了一个通用的调用函数,其功能如下:
对于如下的lua脚本,
test.lua:
我要在C++中调用它的add方法:
这里的call_va
就是所说的通用调用函数,
-
add: 表示要调用的lua函数名字
-
dd>d
: d 表示double, >
之前的两个d,表示有两个输入参数分别是double, double; >
后面的一个d表示返回一个double
-
x : 对应于dd>d
中第1个d, 输入参数
-
y : 对应于dd>d
中第2个d, 输入参数
-
z : 对应于dd>d
中第3个d, 输出参数 —— 即返回值。
下面给出的call_va
函数的实现与书中实现上略有区别,PIL是C语言风格的代码,这里是C++风格的代码:
测试用例:
lua脚本:res/extend_demo.lua
这个实现还要修改一下:
-
- 兼容返回char*
- 在C++中打开lua标准库,让res/extend_demo.lua中可以使用lua标准库里的函数
修改之后再回来修改 to be continue…
在这里也能看到这篇文章:github博客, CSDN博客, 欢迎访问