Skip to content
/ nua Public

header-only bindings to Lua

License

MIT, Zlib licenses found

Licenses found

MIT
LICENSE
Zlib
ORIGINAL-LICENSE
Notifications You must be signed in to change notification settings

lucklove/nua

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nua

Simple C++11 friendly header-only bindings to Lua

A component of PM-Game-Server.
Reference to Selene and fix some features to meet the PM-Game-Server's requirements


依赖

  • cmake 2.8+(可选, 如果不编译测试用例就不用)
  • lua 5.2+
  • 一个支持C++14的编译器(最好不要是clang, 因为用它过不了测试用例, 推荐gcc)

特性与用法

创建lua context

nua::Context ctx;

如果不需要打开lua标准库:

nua::Context ctx{false};

当nua::Context析构时, 所有其关联的资源都会被回收(包括通过值传入的C++对象)

载入lua文件

ctx.load("path/to/your.lua");

直接执行lua代码

ctx(R"(print("hello, world"))");

向lua注册c++的函数

ctx["foo"] = []{ std::cout << "hello, nua" << std::endl; };     /**< lambda */
ctx["bar"] = std::function<...>(...);                           /**< stl function */
ctx["barz"] = std::bind(...);                                    
struct T
{
    type operator()(...)
    {
        ...
    }
} callable;

ctx["func"] = callable;                                         /**< callable object */

之后你可以在lua中调用这些函数

在C++中调用lua的函数

ctx["foo"]();                                                   /**< 没有返回值和参数 */
ctx["bar"](1, 2, "hello").get<int>();                           /**< 获取int返回值 */
int x;
std::string y;
std::tie(x, y) = ctx["barz"](1, 2, 3).get<int, std::string>();  /**< 接收多返回值 */

注册C++的类

struct T
{
    int v;
    int func(int y);
};
ctx.setClass<T>("v", &T::v, "func", &T::func);

然后可以在lua中这样访问这个类:

function bar(t)
    print(t:v())            --访问T::v
    t:set_v(123)            --设置T::v
    t:func(123)             --调用T::func
end

当然, t需要由C++传给lua:

T t;
ctx["bar"](t);

传递引用

通过setClass向nua注册过的类都可以传递引用

struct T
{
    T(const T&) = delete;
} t;

ctx["foo"](std::ref(t));
ctx["bar"](std::cref(t));       /**< 当传递const ref时不会生成相应的set_xxx, 同时非const成员函数也会无效 */

向lua返回引用

ctx["foo"] = [&]() -> const T& { return t; };

C++接收lua函数

-- test.lua

function add(a, b)
    return a + b 
end

function pass_add(x, y)
    return take_fun_arg(add, x, y)
end
nua::Context ctx;
ctx["take_fun_arg"] = [](nua::function<int(int, int)> func, int a, int b)
{
    return func(a, b); 
};

ctx.load("test.lua");
assert(ctx["pass_add"](3, 5) == 8);

lua中利用C++的多态

nua::Context ctx;

struct B
{
    virtual void apply() const
    {
        std::cout << "apply B" << std::endl;
    }
};

struct T : B
{
    void apply() const override
    {
        std::cout << "apply T" << std::endl;
    }
};

ctx.setClass<B>("apply", &B::apply);

T t;
B& rt = t;

ctx(R"(
    function apply(b)
        b:apply()
    end
)");
ctx["apply"](std::cref(rt));

注意

  • 基本类型的对象的引用不能传递给nua, 也不能在传递给nua的函数中作为返回值(仅const引用可以作为参数), 也不能从lua返回, 基本类型包括所有的数字类型, std::string, std::nullptr_t, nua::function
ctx(R"(
    function foo(x)
    end
)");
int x = 0;
ctx["foo"](x);             /**< 合法 */
ctx["foo"](std::ref(x));   /**< 非法 */
ctx["foo"](std::cref(x));  /**< 非法 */

另外, 注意到std::string也是基本类型:

ctx["foo"] = [](const std::string& s) {...};        /**< 合法, 接收基础类型的const引用 */
ctx["foo"] = []() -> const std::string& {...};      /**< 非法, 试图返回基础类型的引用 */
  • 以reference传入nua的对象才可以以reference的形式返回C++, 并且要保证const修饰正确
struct T
{
};

ctx.setClass<T>();
ctx(R"(
    function forward_ref(x)
        return x
    end
)");  

T t;
ctx["forward_ref"](t).get<const T&>();                  /**< 非法, 要求返回t的reference但是传入时不是引用 */
ctx["forward_ref"](t).get<T&>();                        /**< 非法, 要求返回t的reference但是传入时不是引用 */
ctx["forward_ref"](std::ref(t)).get<const T&>();        /**< 合法 */
ctx["forward_ref"](std::cref(t)).get<const T&>();       /**< 合法 */
ctx["forward_ref"](std::cref(t)).get<T&>();             /**< 非法, 不能从const reference转到reference */

About

header-only bindings to Lua

Resources

License

MIT, Zlib licenses found

Licenses found

MIT
LICENSE
Zlib
ORIGINAL-LICENSE

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published