Передать объект C++ в функцию Lua

У меня есть проект C++, где 1 метод 1 класса меняется очень часто. Поэтому я хочу взять этот код с C++ на Lua. Заметьте, я новичок в Lua.

всего задач:

  1. привязать некоторые методы класса к машине состояния Lua;
  2. передать ссылку на объект класса функции, написанной на Lua;
  3. работать с переданным объектом C++ в функции Lua.

Я нашел, как сделать первый шаг с Lunar, и не могу справиться со вторым и третье.

Я не могу использовать SWIG и boost.

3 ответов


//This has a large number of steps, but I'm gonna post them all. This is all using native Lua 5 and the lua CAPI.
int CreateInstanceOfT(lua_State* L) {
    new (lua_newuserdata(L, sizeof(T))) T(constructor args);
    return 1;
}
int CallSomeFuncOnT(lua_State* L) {
    if (lua_istable(L, 1)) { // If we're passed a table, get CData
        lua_getfield(L, 1, "CData");
        lua_replace(L, 1);
    }
    if (!lua_touserdata(L, 1))
        lua_error(L); // longjmp out.
    T& ref = *(T*)lua_touserdata(L, 1);
    ref.SomeFunc(); // If you want args, I'll assume that you can pass them yourself
    return 0;
}
int main() {
    lua_State* L = luaL_newstate();
    lua_pushcfunction(L, CreateInstanceOfT);
    lua_setglobal(L, "CreateInstanceOfT");
    lua_pushcfunction(L, CallSomeFuncOnT);
    lua_setglobal(L, "CallSomeFuncOnT");
    luaL_dofile(L, "something.lua");
    lua_close(L);
}
-- Accompanying Lua code: semicolons are optional but I do out of habit. In something.lua
function CreateCInstance()
    local Instance = {
        CData = CreateInstanceOfT();
        SomeFunc = CallSomeFuncOnT;
    }
    return Instance;
end

local object = CreateCInstance();
object:SomeFunc(); // Calls somefunc.

я мог бы опубликовать большое количество деталей о том, как сделать экспозицию проще, и как сделать наследование, и тому подобное - и его нужно будет изменить, если вы хотите выставить более одного T (я думаю, что наиболее распространенным решением является простой struct { std::auto_ptr<void>, int type } сделка). Но это должно быть отправной точкой, если вы ничего не понимаете в этом процессе.

Bascally, сначала мы просим Lua выделить некоторое пространство (userdata), а затем поместить T в него. Когда CallSomeFuncOnT приходит, сначала мы спрашиваем это если у нас есть таблица (многие классы Lua основаны вокруг таблиц, поскольку они поддерживают ориентацию объекта, метатабли и т. д.), И получаем userdata, который мы затем преобразуем в указатель на наш объект, а затем преобразуем в ссылку. Помните, что lua_touserdata дает вам пустоту*, поэтому вам лучше быть чертовски уверенным в том, что на другом конце. Затем мы вызываем somefunc и возвращения. В основном, мы просто регистрируем функции как глобалы.

теперь, в Lua, когда вы вызываете CreateInstanceOfT, это эффективно просто вызывает конструктор T, прозрачно для пользователя Lua. Затем мы бросаем его в стол, что проще для новичков Lua, и называем SomeFunc, передавая ему этот стол.


вы взглянули на luabind? Это позволяет довольно легко предоставлять объекты и функции C++ LUA.


Как Джон, я использовал luabind и рекомендую его. Однако, поскольку использование boost не является вариантом для вас, вы можете найти список библиотек на этой странице полезная. Вы также можете проверить DoItYourselfCppBinding страница на lua - пользователи wiki.

одна библиотека, указанным на странице oolua, который не имеет зависимостей (так он говорит).