LuaIntf初探

栏目: Lua · 发布时间: 6年前

内容简介:很久很久以前我想给一个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

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Masterminds of Programming

Masterminds of Programming

Federico Biancuzzi、Chromatic / O'Reilly Media / 2009-03-27 / USD 39.99

Description Masterminds of Programming features exclusive interviews with the creators of several historic and highly influential programming languages. Think along with Adin D. Falkoff (APL), Jame......一起来看看 《Masterminds of Programming》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

SHA 加密
SHA 加密

SHA 加密工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具