Невозможно изменить объекты, переданные в lua

Рассмотрим следующий пример использования LuaBridge для передачи объектов в скрипт lua:

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()
;

Очевидно, переданная переменная не может быть изменена с помощью lua:

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

Выше код распечатывает 10 ,

Также в C++ после обработки скрипта переменная все еще сохраняет свое начальное значение.

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

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

Однако простые скалярные типы данных (такие как float), которые не являются членами объекта, могут быть изменены. Я что-то пропустил?


Редактировать: это, по-видимому, можно изменить, если я заменю Test t1(10); с Test *t1 = new Test(10); или даже Test t(10); Test *t1 = &t; и еще пройти &t1 добавить переменную. Я не очень понимаю это поведение, может кто-нибудь объяснить? (адрес по адресу?)

1 ответ

Решение

LuaBridge делает копию вашего аргумента. Если вы сами определите конструктор копирования и поставите там точку останова, вы перейдете с

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

Это просто контракт передачи параметров в LuaBridge. Я думаю, это так, поскольку данные имеют управляемое время жизни C++, и это функция безопасности. Вы можете переписать ваши данные с новым значением, и вы получите то, что вы хотите:

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)

Выведение

10
12
12

и ваша C++ - сторона t1 будет иметь значение d 12

Другие вопросы по тегам