zoukankan      html  css  js  c++  java
  • UDLua

    UDLua

    https://zhuanlan.zhihu.com/p/356694688

    Lua 只有“贫瘠”的 oop,利用元表实现,功能满满但十分原始。我来试着改善这个体验。

    我前段时间写了一篇关于 C++ 动态反射库的文章

    https://zhuanlan.zhihu.com/p/337200770

    实际上,我这个动态库,设计已经出色到可以轻松成为一个跨语言的类型框架。

    本文就来演示一下 Lua 装配上 C++ OOP 后可以多神奇!

    项目地址:

    https://github.com/Ubpa/UDLua

    How to use

    the example code is here

    Suppose you need to use struct vec

    struct vec {
      float x;
      float y;
      float norm() const { return std::sqrt(x * x + y * y); }
    };

    Manual registration on Lua

    if you want to do it on C++, check out this link ->.

    local vec = UDRefl.RegisterType({
      type = "vec",
      fields = {
        { type = "float32", name = "x" },
        { type = "float32", name = "y" },
      },
      methods = {
        {
          name = "norm",
          result = "float32",
          body = function (p)
            return math.sqrt(UDRefl.unbox(p.x * p.x + p.y * p.y))
          end
        }
      }
    })

    Iterate over members

    for iter in ObjectView.new(vec):GetFields():__range() do
      local name, info = iter:__indirection():__tuple_bind()
      print(name:GetView())
    end
    
    for iter in ObjectView.new(vec):GetMethods():__range() do
      local name, info = iter:__indirection():__tuple_bind()
      print(name:GetView())
    end

    Constructing types

    v = SharedObject.new(vec)
    print(v:GetType():GetName()) -- prints "vec"

    Set/get variables

    v.x = 3
    v.y = 4
    print("x: " .. v.x) -- prints "3"

    Invoke Methods

    print("norm: " .. v:norm()) -- prints "5"

    Iterate over varables

    for iter in v:GetTypeFieldVars():__range() do
      local name, var = iter:__indirection():__tuple_bind()
      print(name:GetView() .. ": ".. var)
    end

    Compiler compatibility

    • Clang/LLVM >= 10.0
    • GCC >= 10.0
    • MSVC >= 1926

    Tested platforms:

    • Windows 10: VS2019 16.8.5

    • Ubuntu 20: GCC 10.2, Clang 11.0

    • MacOS 11.0 : GCC 10.2

      AppleClang 12 and Clang 11 is not supported

    0x02. 设计思路

    步骤如下

    • 开发一套世界最强的 C++ 动态反射库 UDRefl
    • 将 UDRefl 中的接口完全注册到其自身中,实现自举
    • 在 lua 中注册 UDRefl,从而 lua 可以借助 UDRefl 操作其上已注册的类型

    这里 UDRefl 扮演的角色是公共类型架构,以 C++ 的 OOP 作为主要参考对象,从而类型架构的性能与能力都充分好。

    而 Lua 只是对接该公共类型架构的一个示例。日后还可以对接 C#,python 等。

    0x03. 类型

    一个类型由类名,基类列表,域,方法以及相应属性而组成。

    类名支持类型系统,基于 C++,支持 const,&,&&。举例说,当你注册了 vec 类型,你可以使用 const{vec},从而禁止成员变量修改。

    类名的细节请参考 C++ 生成式的编译期类型名

    对象的空间设计成连续的,与 C/C++ 一致,根据基类和域的大小与对齐就可以自动算出基类偏移和域偏移。

    方法分成员variable函数,成员const函数,静态函数。其中成员函数会将首个参数设置成 this。对于特殊的函数(构造,析构,运算符等),用户可将其命名成meta函数名(__ctor__dtor__add__mul等),当在 lua 使用 SharedObject.new,运算符时,会去调用这些函数。

    0x04. 域

    在 C++ 中使用 UDRefl 时,获取域的方式为 v.Var("x"),而在 Lua 中就十分自然,可直接写成 v.x

    需要特别注意的是 Lua 中的对对象本身的赋值没法用元表重定义(但对对象成员的赋值是可以重定义的),所以我设计了特殊的域名 self用来获取它本身,示例为 v.self = w

    0x05. 方法

    在 C++ 中使用 UDRefl 时,方法调用的方式为 v.Invoke("norm"),而在 Lua 中就十分自然,可直接写成 v:norm()

    类型定义中,使用类型数组 params 来声明参数类型。函数调用时,支持参数的自动类型转换,只要形参类型存在实参类型的构造函数即可,并且支持 &/&& 的各种转换(如 int-> int&&)。

    另外还支持泛型参数,就像 C++ 的模板一样。即,当参数类型为 Ubpa::UDRefl::ObjectView 时,UDRefl 就将其视为泛型。

    支持成员函数,这时第一个参数就是 this

    0x06. 属性

    属性 Attribute 同于 C# 的 Attribute,也就是挂在域,方法和类型上的对象。属性的类型完全可以是用户自定义的类型,并且支持任意的初始化。

    ============= End

  • 相关阅读:
    Zabbix的前台SQL注射漏洞利用
    LeetCode OJ--Permutation Sequence *
    LeetCode OJ--Next Permutation *
    LeetCode OJ--Permutations II
    LeetCode OJ--Permutations *
    小算法-计算下一个排列
    LeetCode OJ--Gas Station**
    LeetCode OJ--Insert Interval **
    LeetCode OJ--Search Insert Position
    Ruby自动化测试(操作符的坑)
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/14579972.html
Copyright © 2011-2022 走看看