An open API service indexing awesome lists of open source software.

https://github.com/vorgestern/luaaide

C++ wrapper for Lua 5.4 API
https://github.com/vorgestern/luaaide

binding cpp library lua

Last synced: about 1 month ago
JSON representation

C++ wrapper for Lua 5.4 API

Awesome Lists containing this project

README

          

# Purpose & Status
Provide a C++ substitute for Lua's C-API that is more expressive and easier to use.

## Status:
- Works as documented
- Purpose more or less fulfilled
- User will occasionally use Lua API directly to fill gaps in the usecases covered by LuaAide.
- Work continues to cover more usecases.

# Usecases
+ **Embedding** Lua in a program, e.g. for configuration or as a plugin
+ **Extending** Scripts by loading binary Lua-modules written with LuaAide
+ **Exposing** C++ Types and functions to Lua scripts

## Embedding Lua

#include
auto Q=LuaStack::New(true, nullptr);
Q<>1;
printf("C++ code receives 21+22=%d\n", Q.toint(-1));

const std::vector A {"Hoppla", "a list", "of strings"};
Q<>1;
const std::string Aconcat(Q.tostring(-1)); // == "Hoppla\na list\nof strings"

## Extending scripts
demomodule.cpp: compile/link to demomodule.so or demomodule.dll

namespace {
// These functions are implemented elsewhere in this Module:
extern "C" int pwd(lua_Stack*);
extern "C" int cd(lua_Stack*);
}

extern "C" int luaopen_demomodule(lua_State*L)
{
LuaStack Q(L);
Q<>LuaField("version")
<>LuaField("pwd")
<>LuaField("cd");
return 1;
}

demo.lua: use as ```lua demo.lua```

local X=require "demomodule"
print("demomodule version", X.version)
..

## Exposing C++ Types
(examples/m1.cpp, examples/m1test.lua)

# Requirements
+ C++ 20
+ Lua 5.4

# How to build

## First take care of submodules ..

Checkout recursively

git clone --recurse-submodules --remote-submodules https://github.com/vorgestern/luaaide.git

or init recursively

git submodule init
git submodule update
cd ulutest
git submodule init
git submodule update

## .. then on Linux
- Install requirements as you see fit. An additional requirement for Linux is objcopy (for tests).
Check with ```make prerequisites```.
- Adapt Makefile if Lua is not at default location.
- make
- *optional*: make test
- Install manually by copying libLuaAide.a and include/LuaAide.h where they belong.
- *optional*: Copy demo alltag.so so it's found by Lua-scripts (LUA_CPATH or LUA_CPATH_5_4)

## .. else on Windows
- Edit buildsys/VS17/Lua.props to point to your Lua-Installation:
* **AdditionalIncludeDirectories**: Include the directory that contains lua.hpp.
* **AdditionalDependencies** Include the import library for Lua 5.4.
* **AdditionalLibraryDirectories** Include the directory where the import library is located.
- LuaAide.lib (Release|Win32) will be built in the root directory, others under buildsys/VS17.
Select a different Konfiguration|Platform in buildsys/VS17/LuaAide.props.
- Build with Visual Studio 2022 (VS17) by launching buildsys/VS17/LuaAide.sln

# How to use

In these examples, it is assumed that Q ist an instance of LuaStack, e.g. from `LuaStack Q(L)`
or `auto Q=LuaStack::New(true, nullptr);`.

## Creating lists and tables

using namespace std;
Q<>LuaField("x") // Pushes {x=1.5, y=0.7, z=-2.1} on to the stack.
<<0.7>>LuaField("y")
<<-2.1>>LuaField("z");

Q< {"A", "B", "C"}; // Pushes {"A", "B", "C"} on the stack.

Q< { // Pushes {x="21", y="22", z="23"} on to the stack.
{"x", "21"}, {"y", "21"}, {"z", "23"}
};

### Storing values in global Lua variables

Q <>LuaGlobal("L1"); // L1={21, 22, 23} is a global variable.

## Accessing data on the Lua stack from C++

Q<>1; // Execute a script to push one result.
auto result=Q.toint(-1); // Read value on top of the stack as integer.
// Result will be 21.

## Calling Lua functions

using namespace std;
Q<>0; // Equiv. of 'error "This was not expected"'
// lua_error is part of the Lua API.

vector A={"a", "b", "c"};
Q<>1; // formatany is part of LuaAide.
auto str=Q.tostring(-1); // It converts any value to a string;

## Creating functions on the stack

## Creating closures

int join(lua_State*L) // demofunction: table.concat with upvalue sep
{
LuaStack Q(L);
Q <>1; // return table.concat(arg, up1)
return 1;
}
Q<<", "<>LuaGlobal("KommaJoin"); // Create Closure that joins with comma.
Q<<"-" <>LuaGlobal("HyphJoin"); // Create Closure that joins with hyphens.

Q<>0;

## Running inline scripts

## Embedding instances of C++ classes

## Calling functions from the Lua runtime

Q<>1;

Q<>1; // Calls table.concat on the list, i.e. pushes
// "First+Second" on to the stack.

## Error handling
### Handling compile-errors in an application that embeds Lua
- Install a PanicHandler to translate Lua-exceptions to C++ runtime exceptions.
- Combine LuaCode with a name in a std::pair to get better error messages.
```
\#include \
using namespace std;

int main_throwing(lua_State*L)
{
LuaStack Q=L;
// Executing this Script will fail because a parenthesis is not closed.
Q<>0;
}

int panichandler(lua_State*L)
{
LuaStack Q(L);
throw runtime_error(Q.errormessage());
return 0;
}

int main()
{
LuaStack Q=LuaStack::New(true, panichandler);
try { return main_throwing(Q); }
catch (const runtime_error&E)
{
printf("Runtime error:\n%s\n", E.what());
cout<>1;
if (rc!=LUA_OK)
{
const auto message=Q.tostring(-1);
// Use as suits your application, e.g. throw a C++ runtime-error.
}
```

### Handling errors when Extending Scripts (i.e. in binary modules)
Throw a conventional Lua-Error, let Lua handle it:

```
int demofunction(lua_State*L)
{
// Called at runtime from Lua, unhappy with arguments:
LuaStack Q(L);
if (height(Q)<1) return Q<<"demofunction: Argument (string) expected">>luaerror;
if (Q.typeat(-1)!=LuaType::TSTRING) return Q<<"demofunction: string expected">>luaerror;
.....
}
```

### Debugtool: Print the Stack

LuaStack Q=...;
cout<