سؤال

Considering the following example of using LuaBridge to pass objects to a lua script:

class Test {
public:
    double d;
    Test(double t): d(t) {};
};
Test t1(10);

auto lua_state = luaL_newstate();
luaL_openlibs(lua_state);

luabridge::getGlobalNamespace(lua_state)
    .beginNamespace("Core")
        .beginClass<Test>("Test")
            .addConstructor<void(*)(double)>()
            .addData("d", &Test::d)
        .endClass()
        .addVariable("t1", &t1)
    .endNamespace()
;

Apparently the passed variable can not be modified by lua:

Core.t1.d = 12
print(Core.t1.d)

The above code prints 10.

Also in C++ after processing the script the variable still holds its initial value.

luaL_dofile(lua_state, ".../test.lua");

std::cout << t1.d << std::endl; // 10

However simple scalar data types (like float) that aren't object members can be modified. Am I missing something?


Edit: It is apparently modifiable if I replace Test t1(10); with Test *t1 = new Test(10); or even Test t(10); Test *t1 = &t; and still pass &t1 to addVariable. I do not really understand that behavior, may someone explain? (address of address?)

هل كانت مفيدة؟

المحلول

LuaBridge makes a copy of your argument. If you define a copy constructor yourself and put a breakpoint there, you'll jump from

/**
  Push T via copy construction from U.
*/
template <class U>
static inline void push (lua_State* const L, U const& u)

This is just a contract of passing parameters in LuaBridge. I guess, it is so, since the datum has the C++ managed lifetime, and this is a safety feature. You can rewrite your datum with a new value, and you'll get what you want:

Core.t1.d = 12
t2 = Core.Test(10)
t2.d=12
print(Core.t1.d)
print(t2.d)
Core.t1 = t2
print(Core.t1.d)

outputting

10
12
12

and your C++ - side t1 will have the d value of 12

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top