LuaIntf初探

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

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

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

查看所有标签

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

We Are the Nerds

We Are the Nerds

Christine Lagorio-Chafkin / Hachette Books / 2018-10-2 / USD 18.30

Reddit hails itself as "the front page of the Internet." It's the third most-visited website in the United States--and yet, millions of Americans have no idea what it is. We Are the Nerds is an eng......一起来看看 《We Are the Nerds》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具