Предоставляемый API Lua интерфейс требует написания адаптеров для методов класса и прямую манипуляцию стеком VM при вызове функции Lua:
```c++
#include <lua.hpp>
#include <iostream>
// Адаптеры методов класса для Lua
static int myobject_setX(lua_State *L) {
(*reinterpret_cast<MyObject **>(luaL_checkudata(L, 1, "MyObject")))->setX(luaL_checknumber(L, 2));
return 0;
}
static int myobject_getX(lua_State *L) {
lua_pushnumber(L, (*reinterpret_cast<MyObject **>(luaL_checkudata(L, 1, "MyObject")))->getX());
return 1;
}
int main(int argc, char **argv) {
// Создание
lua_State *L = luaL_newstate();
luaL_openlibs(L);
luaL_dofile(L, "library.lua");
// Создание метатаблицы для класса С++
luaL_newmetatable(L, "MyObject");
// Регистрация методов метатаблицы
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, myobject_setX);
lua_setfield(L, -2, "setX");
lua_pushcfunction(L, myobject_getX);
lua_setfield(L, -2, "getX");
// удаление адреса метатаблицы с вершины стека
lua_pop(L, 1);
// экспорт существующего объекта
*reinterpret_cast<MyObject **>(lua_newuserdata(L, sizeof(MyObject *))) = &object;
// установка мтетаблицы для объекта
luaL_setmetatable(L, "MyObject");
// задание имени для объекта
lua_setglobal(L, "object");
// Обращение к объекту в Lua
luaL_dostring(L, "object:setX(object:getX()*2)");
std::cout << object.getX()<< "\n";
// Вызов функции Lua из C++
// Получение адреса функции
lua_getglobal(L, "calc");
// Размещение аргументов
lua_pushnumber(L, 10);
lua_pushnumber(L, 20);
// Вызов функции
lua_call(L, 2, 1);
// Извлечение результата и удаление из стека
double result = lua_tonumber(L, -1);
lua_pop(L, 1);
std::cout << "Результат: " << result << "\n";
lua_close(L);
}
```
Библиотека [sol2](https://github.com/ThePhD/sol2) обеспечивает автоматическое создание функций-адаптеров
по описанию интерфейса и простой способ для вызова функций Lua: