Как ссылаться на 'this' в лямбде, используемой со скриптом LUA - PullRequest
1 голос
/ 07 апреля 2020

Я пытаюсь добавить LUA API к моей программе на C ++ и пытаюсь разрешить сценарию рисовать на моем GUI. До сих пор у меня есть это для моей лямбда-функции:

auto addToDrawList = [](lua_State* L) -> int
{
    int DrawType = (int)lua_tonumber(L, -2);
    std::string Label = (std::string)lua_tostring(L, -1);

    bool found = false;
    for (int i = 0; i <= DrawList.size(); i++)
    {
        if (DrawList[i].Active == false && !found)
        {
            switch (DrawType)
            {
            case(0):
                break;
            case(1):
                DrawList[i].Active = true;
                DrawList[i].DrawType = Type::TextBox;
                DrawList[i].Label = Label;
                break;
            }
            found = true;
        }
    }

    return 0;
};

Это как мой LUA выполняемый скрипт:

const char* LUA_FILE = R"(
    addToDrawList(1, "Test")
)";

Вот как я толкаю свою функцию к LUA stack:

lua_State* L = luaL_newstate();

lua_newtable(L);
int uiTableInd = lua_gettop(L);
lua_pushvalue(L, uiTableInd);
lua_setglobal(L, "Ui");

lua_pushcfunction(L, addToDrawList);
lua_setfield(L, -2, "addToDrawList");

Проблема в моем первом скрипте, так как он не может получить массив DrawList, поскольку он находится внутри this.

Итак, чтобы решить эту проблему, я попытался добавить this в список захвата лямбды, выполнив следующее:

auto addToDrawList = [this](lua_State* L) -> int

, которое, как оказалось, работало и устранило ошибку, но затем у меня возникла проблема с последним сценарием:

lua_pushcfunction(L, addToDrawList);

Error

Я искал в Inte rnet исправление, но не могу его найти.

1 Ответ

1 голос
/ 07 апреля 2020

lua_pushcfunction() принимает указатель на функцию C. лямбда без захвата может быть преобразована в такой указатель функции, но лямбда захвата не может.

Использовать lua_pushcclosure() 1 вместо. Это позволит вам связать пользовательские значения (известные как upvalues ​​) с функцией C, такой как указатель this или просто указатель на DrawList, et c.

Когда создается функция C, с ней можно ассоциировать некоторые значения, создавая, таким образом, C замыкание (см. §3.4 ); эти значения становятся доступными для функции всякий раз, когда она вызывается . Чтобы связать значения с функцией C, сначала эти значения должны быть помещены в стек (при наличии нескольких значений первое значение помещается первым). Затем вызывается lua_pushcclosure для создания и размещения в стеке функции sh C с аргументом n, указывающим, сколько значений следует связать с функцией. lua_pushcclosure также извлекает эти значения из стека.

1: lua_pushcfunction() - это просто оболочка для lua_pushcclosure() с заданными значениями 0.

Например:

auto addToDrawList = [](lua_State* L) -> int
{
    const MyClassType *pThis = (const MyClassType*) lua_topointer(L, lua_upvalueindex(1));

    // use pThis->DrawList as needed...

    return 0;
};

...

lua_State* L = luaL_newstate();
...
//lua_pushcfunction(L, addToDrawList);
lua_pushlightuserdata(L, this);
lua_pushcclosure(L, addToDrawList, 1);
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...