内容简介:很久很久以前我想给一个C++项目(简称H吧)加lua支持,于是我就去努力地看lua文档,想把lua那蜜汁栈交互方式。以下讨论的都是Lua的C语言官方库。它和C是这么交互的 - 例如说让你把东西都塞一个栈上然后调用各种方法给予里面的数据在Lua世界的生命,Lua调用C程序也是,把参数压栈里面,返回的也压栈里面:因为Lua允许多返回值,这可比别的语言还要加Array Tuple之类的返回多个值简单多了不是吗。不过这个栈应该是只用来和C交互的。
很久很久以前
我想给一个C++项目(简称H吧)加 lua 支持,于是我就去努力地看lua文档,想把lua那蜜汁栈交互方式。以下讨论的都是Lua的 C语言 官方库。
它和C是这么交互的 - 例如说让你把东西都塞一个栈上然后调用各种方法给予里面的数据在Lua世界的生命,Lua调用C程序也是,把参数压栈里面,返回的也压栈里面:因为Lua允许多返回值,这可比别的语言还要加Array Tuple之类的返回多个值简单多了不是吗。不过这个栈应该是只用来和C交互的。
这个太难懂了,肯定要找helper/binding库嘛。第一个是 lua-icxx
,它本来设定便是生成动态链接库的,但是我要静态链接啊,所以在这一步也花了不少时间。它有一个好,目前我用过的,例如说这样:
LuaInterpreter L; constexpr auto script = "Your script here"; LuaFuncRef chunk = L.chunkFromString(script); if(chunk.isError()) { // cannot load script } else { // ok } LuaTempResult res = chunk(); // yes like this you can pass arguments if you need. if(res.isError()) { // error running, error is res.getErrMsg() }
它可以很方便地调用lua函数blabla。
另外 lua-icxx
是一个放在SF的SVN repo,要下载源代码有点绕hhh
但是要绑定module啊class啊它就不行了。另外一个 LuaIntf
的库在这方面就友好多了,它不仅帮你封装了返回非基础类型的东西时userdata的操作(包括new啊check啊还有gc),它还可以很方便地构建一个class或者是module。
就像是给imgui的 ImVec2
绑定个吧,
LuaBinding(L) .beginClass<ImVec2>("ImVec2") .addConstructor(LUA_ARGS(_opt<float>, _opt<float>)) .addProperty("x", [](ImVec2 *self) { return self->x; }, [](ImVec2 *self, float val) { self->x = val; }) .addProperty("y", [](ImVec2 *self) { return self->y; }, [](ImVec2 *self, float val) { self->y = val; }) .endClass();
addConstructor()
那个 LUA_ARGS
似乎省略不了。
在脚本里面就是这样子的了:
local a = ImVec2() -- all default val a = ImVec(2.3) -- partial default val a.x -- get a.y = 9.03 -- set
是吧很方便吧2333
对于例如说 someStruct* someFunc(anotherClass* param)
这样子的话,你就需要给它绑定 someStruct
anotherClass
之后就可以愉快地使用啦(上面 ImVec2
也是个struct哟)。
它绑定重载函数有点儿麻烦,我建议使用lambda无痛解决。而且有时候返回boolean的函数绑定好像有问题,这时用lambda wrap一下就好啦
但是它不自带 void*
的解决方案,这里我提供一个(记得引入头文件):
namespace LuaIntf { template<> struct LuaTypeMapping<void*> { static void push(lua_State *L, void* ptr) { lua_pushinteger(L, (lua_Integer)ptr); } static void* get(lua_State *L, int index) { return (void*)luaL_checkinteger(L, index); } static void* opt(lua_State *L, int index, void* def) { return lua_isnoneornil(L, index) ? def : get(L, index); } }; }
默认的 lua_integer
其实已经可以存下指针了。
另外Lua没有 continue
这种流程控制,例如说
while(foo) { if(sth) continue; bar }
这些就应该:
while foo do if not sth then bar end end
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。