LuaIntf初探

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

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

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

查看所有标签

猜你喜欢:

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

深入理解计算机系统

深入理解计算机系统

Randal E.Bryant、David O'Hallaron / 龚奕利、雷迎春 / 中国电力出版社 / 2004-5-1 / 85.00元

从程序员的视角,看计算机系统! 本书适用于那些想要写出更快、更可靠程序的程序员。通过掌握程序是如何映射到系统上,以及程序是如何执行的,读者能够更好的理解程序的行为为什么是这样的,以及效率低下是如何造成的。粗略来看,计算机系统包括处理器和存储器硬件、编译器、操作系统和网络互连环境。而通过程序员的视角,读者可以清晰地明白学习计算机系统的内部工作原理会对他们今后作为计算机科学研究者和工程师的工作有......一起来看看 《深入理解计算机系统》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码