luabind成员函数需要以对象作为第一个参数。

我在使用 luabind v0.9.1,g++ 4.7 (--std=c++11)和 Boost 1.51时遇到了一个非常微妙的问题,可以在以下代码中重现:

#include <exception>
#include <iostream>
#include <string>

#include <lua.hpp>
#include <luabind/luabind.hpp>

struct TestObject
{
    int x = 0;

    int increment()
    {
        return ++x;
    }
};

static void luaError(lua_State* stack, const std::string& luaCode, int luaErr)
{
    std::cerr << "Failed with code " << luaErr << ": " << std::endl
              << "LuaCode: " << luaCode << std::endl
              << "Message: " << lua_tostring(stack, -1) << std::endl;
    std::terminate();
}

void luaExec(lua_State* stack, const std::string& luaCode)
{
    if (int excode = luaL_loadbuffer(stack, luaCode.c_str(), luaCode.size(), "luaExec"))
        luaError(stack, luaCode, excode);

    if (int excode = lua_pcall(stack, 0, 0, 0))
        luaError(stack, luaCode, excode);
}

int main()
{
    using namespace luabind;
    lua_State* L = luaL_newstate();
    open(L);

    module(L)
    [
        class_<TestObject>("TestObject")
            .def(constructor<>())
            .def("increment", &TestObject::increment)
            .property("x", &TestObject::x)
    ];

    luaExec(L, "obj = TestObject()");
    luaExec(L, "obj.increment()");
}

编译并执行此代码会导致:

Failed with code 2:
LuaCode: obj.increment()
Message: No matching overload found, candidates:
int increment(TestObject&)

然而,如果我将第二个 luaExec 调用更改为 luaExec(L, "obj.increment(obj)");,代码就可以正常执行。这种行为非常奇怪。我在这里做错了什么?

点赞
用户950747
用户950747

在使用 luabind 绑定的对象上调用方法需要使用 object:method(arg1, arg2,...) 语法。这是 "语法糖",其本质是 object.method(object, arg1, arg2, ....)。这样做可以调用正确的方法(即对象自身的方法),同时也将正确的数据成员(即对象自身的数据成员)传递进去。有关在 Lua 中直接构建类的更多信息,请参见 http://lua-users.org/wiki/SimpleLuaClasses:这对使用 luabind 绑定的类有所帮助。

2012-11-11 15:53:57