{"id":22454276,"url":"https://github.com/vorgestern/luaaide","last_synced_at":"2026-05-02T09:32:43.998Z","repository":{"id":262524799,"uuid":"887505929","full_name":"vorgestern/LuaAide","owner":"vorgestern","description":"C++ wrapper for Lua 5.4 API","archived":false,"fork":false,"pushed_at":"2025-02-14T04:46:16.000Z","size":282,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-27T13:15:50.605Z","etag":null,"topics":["binding","cpp","library","lua"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vorgestern.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-12T21:04:43.000Z","updated_at":"2025-02-14T04:46:19.000Z","dependencies_parsed_at":"2024-12-01T13:22:18.244Z","dependency_job_id":"d96b556f-13ae-4704-a337-ebe95355c3bb","html_url":"https://github.com/vorgestern/LuaAide","commit_stats":null,"previous_names":["vorgestern/luaaide"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vorgestern%2FLuaAide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vorgestern%2FLuaAide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vorgestern%2FLuaAide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vorgestern%2FLuaAide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vorgestern","download_url":"https://codeload.github.com/vorgestern/LuaAide/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245850360,"owners_count":20682647,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binding","cpp","library","lua"],"created_at":"2024-12-06T07:07:28.634Z","updated_at":"2026-05-02T09:32:43.952Z","avatar_url":"https://github.com/vorgestern.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Purpose \u0026 Status\nProvide a C++ substitute for Lua's C-API that is more expressive and easier to use.\n\n## Status:\n- Works as documented\n- Purpose more or less fulfilled\n- User will occasionally use Lua API directly to fill gaps in the usecases covered by LuaAide.\n- Work continues to cover more usecases.\n\n# Usecases\n+ **Embedding** Lua in a program, e.g. for configuration or as a plugin\n+ **Extending** Scripts by loading binary Lua-modules written with LuaAide\n+ **Exposing** C++ Types and functions to Lua scripts\n\n## Embedding Lua\n\n    #include \u003cLuaAide.h\u003e\n    auto Q=LuaStack::New(true, nullptr);\n    Q\u003c\u003cLuaCode(\"local a,b=...; return a+b\")\u003c\u003c21\u003c\u003c22\u003e\u003e1;\n    printf(\"C++ code receives 21+22=%d\\n\", Q.toint(-1));\n\n    const std::vector\u003cstd::string\u003e A {\"Hoppla\", \"a list\", \"of strings\"};\n    Q\u003c\u003cLuaCode(R\"xx(return table.concat(..., \"\\n\"))xx\")\u003c\u003cA\u003e\u003e1;\n    const std::string Aconcat(Q.tostring(-1)); // == \"Hoppla\\na list\\nof strings\"\n\n## Extending scripts\ndemomodule.cpp: compile/link to demomodule.so or demomodule.dll\n\n    namespace {\n        // These functions are implemented elsewhere in this Module:\n        extern \"C\" int pwd(lua_Stack*);\n        extern \"C\" int cd(lua_Stack*);\n    }\n\n    extern \"C\" int luaopen_demomodule(lua_State*L)\n    {\n        LuaStack Q(L);\n        Q\u003c\u003cLuaTable()\n            \u003c\u003c\"0.1\"\u003e\u003eLuaField(\"version\")\n            \u003c\u003cpwd\u003e\u003eLuaField(\"pwd\")\n            \u003c\u003ccd\u003e\u003eLuaField(\"cd\");\n        return 1;\n    }\n\ndemo.lua: use as ```lua demo.lua```\n\n    local X=require \"demomodule\"\n    print(\"demomodule version\", X.version)\n    ..\n\n## Exposing C++ Types\n(examples/m1.cpp, examples/m1test.lua)\n\n# Requirements\n+ C++ 20\n+ Lua 5.4\n\n# How to build\n\n## First take care of submodules ..\n\nCheckout recursively\n\n    git clone --recurse-submodules --remote-submodules https://github.com/vorgestern/luaaide.git\n\nor init recursively\n\n    git submodule init\n    git submodule update\n    cd ulutest\n    git submodule init\n    git submodule update\n\n## .. then on Linux\n- Install requirements as you see fit. An additional requirement for Linux is objcopy (for tests).\n  Check with ```make prerequisites```.\n- Adapt Makefile if Lua is not at default location.\n- make\n- *optional*: make test\n- Install manually by copying libLuaAide.a and include/LuaAide.h where they belong.\n- *optional*: Copy demo alltag.so so it's found by Lua-scripts (LUA_CPATH or LUA_CPATH_5_4)\n\n## .. else on Windows\n- Edit buildsys/VS17/Lua.props to point to your Lua-Installation:\n  * **AdditionalIncludeDirectories**: Include the directory that contains lua.hpp.\n  * **AdditionalDependencies** Include the import library for Lua 5.4.\n  * **AdditionalLibraryDirectories** Include the directory where the import library is located.\n- LuaAide.lib (Release|Win32) will be built in the root directory, others under buildsys/VS17.\n  Select a different Konfiguration|Platform in buildsys/VS17/LuaAide.props.\n- Build with Visual Studio 2022 (VS17) by launching buildsys/VS17/LuaAide.sln\n\n# How to use\n\nIn these examples, it is assumed that Q ist an instance of LuaStack, e.g. from `LuaStack Q(L)`\nor `auto Q=LuaStack::New(true, nullptr);`.\n\n## Creating lists and tables\n\n    using namespace std;\n    Q\u003c\u003clualist\u003c\u003c21\u003c\u003c22\u003c\u003c23;                         // Pushes {21, 22, 23} on to the stack.\n\n    Q\u003c\u003cLuaTable()\u003c\u003c1.5\u003e\u003eLuaField(\"x\")               // Pushes {x=1.5, y=0.7, z=-2.1} on to the stack.\n                \u003c\u003c0.7\u003e\u003eLuaField(\"y\")\n                \u003c\u003c-2.1\u003e\u003eLuaField(\"z\");\n\n    Q\u003c\u003cvector\u003cstring\u003e {\"A\", \"B\", \"C\"};              // Pushes {\"A\", \"B\", \"C\"} on the stack.\n\n    Q\u003c\u003cunordered_map\u003cstring,string\u003e {               // Pushes {x=\"21\", y=\"22\", z=\"23\"} on to the stack.\n        {\"x\", \"21\"}, {\"y\", \"21\"}, {\"z\", \"23\"}\n    };\n\n### Storing values in global Lua variables\n\n    Q   \u003c\u003clualist\u003c\u003c21\u003c\u003c22\u003c\u003c23\u003c\u003clualistend\n        \u003e\u003eLuaGlobal(\"L1\");                          // L1={21, 22, 23} is a global variable.\n\n## Accessing data on the Lua stack from C++\n\n    Q\u003c\u003cLuaCode(\"return 21\")\u003e\u003e1;                     // Execute a script to push one result.\n    auto result=Q.toint(-1);                        // Read value on top of the stack as integer.\n                                                    // Result will be 21.\n\n## Calling Lua functions\n\n    using namespace std;\n    Q\u003c\u003clua_error\u003c\u003c\"This was not expected\"\u003e\u003e0;       // Equiv. of 'error \"This was not expected\"'\n                                                    // lua_error is part of the Lua API.\n\n    vector\u003cstring\u003e A={\"a\", \"b\", \"c\"};\n    Q\u003c\u003cformatany\u003c\u003cA\u003e\u003e1;                             // formatany is part of LuaAide.\n    auto str=Q.tostring(-1);                        // It converts any value to a string;\n\n## Creating functions on the stack\n\n## Creating closures\n\n    int join(lua_State*L)                                   // demofunction: table.concat with upvalue sep\n    {\n        LuaStack Q(L);\n        Q   \u003c\u003cLuaGlobal(\"table\")\u003c\u003cLuaDotCall(\"concat\")      // local arg=...\n            \u003c\u003cLuaValue(1)\u003c\u003cLuaUpValue(1)\u003e\u003e1;                // return table.concat(arg, up1)\n        return 1;\n    }\n    Q\u003c\u003c\", \"\u003c\u003cLuaClosure({join, 1})\u003e\u003eLuaGlobal(\"KommaJoin\"); // Create Closure that joins with comma.\n    Q\u003c\u003c\"-\" \u003c\u003cLuaClosure({join, 1})\u003e\u003eLuaGlobal(\"HyphJoin\");  // Create Closure that joins with hyphens.\n\n    Q\u003c\u003cLuaCode(R\"__(                                        // Execute demo script\n        local A={\"a\", \"b\", \"c\"}\n        print(KommaJoin(A))                                 // prints \"a, b, c\"\n        print(HyphJoin(A))                                  // prints \"a-b-c\"\n    )__\")\u003e\u003e0;\n\n## Running inline scripts\n\n## Embedding instances of C++ classes\n\n## Calling functions from the Lua runtime\n\n    Q\u003c\u003cLuaGlobal(\"string\")\u003c\u003cLuaDotCall(\"format\")    // Pushes \"vector=[21, 22, 23]\" on to the stack.\n     \u003c\u003c\"vector=[%s, %s, %s]\"\u003c\u003c21\u003c\u003c22\u003c\u003c23\u003e\u003e1;\n\n    Q\u003c\u003clualist\u003c\u003c\"First\"\u003c\u003c\"Second\";                  // Pushes {\"First\", \"Second\"} on to the stack.\n    Q\u003c\u003cLuaGlobal(\"table\")\u003c\u003cLuaDotCall(\"concat\")\n     \u003c\u003cLuaValue(-2)\u003c\u003c\"+\"\u003e\u003e1;                        // Calls table.concat on the list, i.e. pushes\n                                                    // \"First+Second\" on to the stack.\n\n## Error handling\n### Handling compile-errors in an application that embeds Lua\n- Install a PanicHandler to translate Lua-exceptions to C++ runtime exceptions.\n- Combine LuaCode with a name in a std::pair to get better error messages.\n    ```\n    \\#include \\\u003cLuaAide.h\\\u003e\n    using namespace std;\n\n    int main_throwing(lua_State*L)\n    {\n        LuaStack Q=L;\n        // Executing this Script will fail because a parenthesis is not closed.\n        Q\u003c\u003cmake_pair(\"FunctioningLuaCompiletimeFailureDemo\", LuaCode(R\"xxx(\n            function map(A, M\n                local R={}\n                for _,e in ipairs(A) do table.insert(R, M[e] or e) end\n                return R\n            end\n        )xxx\"))\u003e\u003e0;\n    }\n\n    int panichandler(lua_State*L)\n    {\n        LuaStack Q(L);\n        throw runtime_error(Q.errormessage());\n        return 0;\n    }\n\n    int main()\n    {\n        LuaStack Q=LuaStack::New(true, panichandler);\n        try { return main_throwing(Q); }\n        catch (const runtime_error\u0026E)\n        {\n            printf(\"Runtime error:\\n%s\\n\", E.what());\n            cout\u003c\u003cQ\u003c\u003c\"\\n\";\n            return 0;\n        }\n    }\n    ```\n\n### Handling runtime-errors in an application that embeds Lua\n- Throw conventional Lua-errors where applicable. Have it translated into\n  a C++ runtime exception as shown above.\n- Handle unexpected results from script execution by checking the return value:\n\n    ```\n    // This script will cause a runtime-error, because table.concat cannot handle\n    // elements of type boolean.\n    const auto rc=Q\u003c\u003cmake_pair(\"Demo\", LuaCode(R\"xx(\n        local a={...}\n        return table.concat(a, \", \")\n    )xx\"))\u003c\u003c21\u003c\u003c22\u003c\u003ctrue\u003c\u003cfalse\u003e\u003e1;\n    if (rc!=LUA_OK)\n    {\n        const auto message=Q.tostring(-1);\n        // Use as suits your application, e.g. throw a C++ runtime-error.\n    }\n    ```\n\n### Handling errors when Extending Scripts (i.e. in binary modules)\nThrow a conventional Lua-Error, let Lua handle it:\n\n    ```\n    int demofunction(lua_State*L)\n    {\n        // Called at runtime from Lua, unhappy with arguments:\n        LuaStack Q(L);\n        if (height(Q)\u003c1) return Q\u003c\u003c\"demofunction: Argument (string) expected\"\u003e\u003eluaerror;\n        if (Q.typeat(-1)!=LuaType::TSTRING) return Q\u003c\u003c\"demofunction: string expected\"\u003e\u003eluaerror;\n        .....\n    }\n    ```\n\n### Debugtool: Print the Stack\n\n    LuaStack Q=...;\n    cout\u003c\u003cQ;\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvorgestern%2Fluaaide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvorgestern%2Fluaaide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvorgestern%2Fluaaide/lists"}