lua编译器_C++ 自动绑定 Lua

Lua 挺好用的,但实际上,我一接触它,首先面临的问题就是复杂的 C++ 与 Lua 间的交互问题,不解决这个,单纯用个 Lua 并没有什么意义。

这个绑定的问题是复杂的,从众多的开源库[1]中就能瞥见端倪。问题的复杂性在于不同语言间交互面临的类型与存储的管理。

C++ 与 Lua 间的绑定,目测有两个流派:手动派和自动派

手动派就是手写栈操作,自动派也至少分两种,其一是靠编译器插件,另一是靠 wrapper。

我选择的方案是最简单的 wrapper 方案,这相关的开源库就挺多。

选择了 wrapper 后,剩下要做的事情就是用这个 wrapper 把 C++ 类注册上,只要结合上

"全球最强" の 99 行 C++ 静态反射库,这并不困难。

结合两相之力,C++ 与 Lua 间的绑定在用户端就变成了 1 行 的事

代码

Ubpa/ULuaPP​github.com
900bdded6aea57a21514c5848aa24860.png

1. Lua wrapper

awesome-cpp 上相关的库有 LuaBridge,Luacxx,sol2,SWIG(编译器)

我选择了其中“最潮”的 sol2 (v3),它文档十分丰富,开源工作搞得非常好。

但其实代码已经很脏了,作者面临各种 bug 已经感觉修不过来了。没办法,再怎么说这也是当前最好之一的库了。主要是来源于问题的复杂性吧。我看库里边真是无所不用其极,连 &/&& 成员函数都有,要处理 unique_ptr, shared_ptr, move, reference 等等麻烦问题。库的代码也来到了 25k 行,就解决这个 wrapper 的问题。问题实在是很复杂。

我还给他修了

不管怎样,用了再说

对于一个 C++ 的类

a8ec005bac5f86221f0a2e4dd41a454c.png

利用 sol2 注册到 Lua 中需要写如下代码

90f60ae4896bd7e378db7c82f96aed7a.png

2. auto bind

在第 1 节中提到了在使用 sol2 时需要写一定的注册代码,我们看到,这个代码,就跟"全球最强" の 99 行 C++ 静态反射库 里的声明极其类似。对于 Point 类,静态反射的声明代码为

e415e077da1f6548243cdc64fec1dbcd.png

假设用户已经声明了静态反射,那么在使用 sol2 时,就可以利用这个静态信息自动生成 sol2 注册代码,此时用户只需写 1 行代码。

bc0e6e5fb45d0c460d5b594bf52b2bc7.png

这行代码里干了什么呢?

  1. 获取构造函数(名字为 "constructor"的 field)组装成 sol::initializers
  2. 将所有函数按名字分组,然后各组分别注册(多函数组注册成 sol::overload,但函数就简单注册)。如果函数名是 operator+operator- 等特殊函数,则注册成 sol::meta_function::*
  3. 将所有变量注册
另外,如 "全球最强" の 99 行 C++ 静态反射库 所述,域还有属性列表,我这里还会将属性注册上,对于重载函数,由于域同名,在注册时会自动加上必要的索引 _0_1 以区分不同的域的属性列表

这其中涉及非常繁重的元编程(复杂度

为函数个数),特别是第 2 点,实现成
constexpr 要做好多的工作,最后只需用下边的函数就能获取到一个类的各重载函数组(这里省略了其调用函数的细节)

67b6fb40ea20dddf30561771d5bd6ee4.png

结果确实是 constexpr

71acf3e9840fe5bbe021342e6d62989f.png

USRefl 库确实用起来挺顺手的,就是 C++ 语言的能力还不够,导致部分内容写法上需要绕。现在体会到了 C++20 的好处了,特别是类常量模板参数和 template lambda,可惜我目前用的 MSVC 只有鸡肋的/std:c++latst。再等等吧,终究是错付了。

3. 示例

下边举一个复杂的例子,包含了上边所讲的所有特性

71639f9ef7cc394cc7f5770308eab454.png
涉及:构造函数(重载),变量,成员函数重载,特殊成员函数( operator-),类属性,变量属性,重载函数属性

静态反射声明

0affae7bbfbe655876af2eca706218e0.png

接着用 sol2 注册到 Lua 中

bc0e6e5fb45d0c460d5b594bf52b2bc7.png

然后在 Lua 里跑下边的代码

72a7af7d51a12adf1e02a83e5ba5386d.png

结果如下

edc55c8df8f070fea7e33b776abfe509.png

完美!

4. 结语

至此,C++ 绑定到 Lua 后,使得我们后续的开发可以直接在 lua 上进行。

这项工作将用于我的引擎之中,供给 UECS 使用。

脚本真香!

参考

  1. ^http://lua-users.org/wiki/BindingCodeToLua
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值