Writing Lua Functions C++
Product & Tech
The C/Invoke Lua Binding uses the new Lua module system, so to use C/Invoke in your Lua programs, load the module like so: require ('cinvokelua') To call C functions easily without writing a Lua module, declare a new instance of the clibrary class to load a dynamic library. The clibrary instance has methods which allow you to load functions.
Introduction
The Roblox engine is written in a combination of C++ and Lua, with the code that performs computationally intensive operations written in optimized C++, while game logic and scripts are written in Lua, for ease of development. For this model to be effective, it requires that the transitions between Lua and C++ be as fast as possible, as any time spent in this no man’s land is essentially just wasted milliseconds.
Over the past couple of months, we’ve been rolling out various improvements to this part of the system. One part specifically—the actual invocation of C++ methods from Lua—was particularly interesting, as it led to considerable speed improvements and required digging around in the guts of Lua to understand how things worked under the hood.
We ended up modifying the Lua VM itself, but before we get to that, we need to lay some groundwork.
Compilers, VM, and bytecode
When Lua source code is compiled, it’s compiled into Lua bytecode, which the Lua VM then runs. Lua bytecode has around 35 instructions in total, for things like reading/writing tables, calling functions, performing binary operations, jumps and conditionals, and so on. The Lua VM is register-based, as opposed to being stack-based like many other VMs, so part of what the compiler does when it generates bytecode is determine which registers each instruction should use.
Each instruction has the form “OP_CODE A B,” or “OP_CODE A B C,” where “OP_CODE” is the opcode (for example, CALL for calling a function) and A/B/C are the opcode arguments. The arguments (or registers) aren’t actual values. Instead, they are indices that point into one of two tables: the constant table (written Kst(..)) or the register table (written R(..)).
Interlude
For a detailed description of Lua bytecode, see “A No-Frills introduction to Lua 5.1 VM Instructions.” It’s a lot more exciting than it sounds; I promise!
To give you a feel for what Lua bytecode looks like, we’re going to go over some simple programs first and then progress to some more relevant examples.
Interlude
Using the Chunkspy utility, we can disassemble Lua bytecode into Lua assembly and get a listing of the code, as well as the constant table, so we can essentially see what bytecode gets generated for any given Lua source code.
Basic bytecode examples
A simple program like “x = 10” compiles into:
The first two lines show the constant table (with the string value “x” in slot 0 and the integer value 10 in slot 1), and the following two lines are the disassembled opcodes.
[Line 1] Looking up the LOADK opcode in “No Frills,” we see that it has the form “LOADK A Bx — R(A) := Kst(Bx).” So, LOADK has two arguments (registers A and B) and its operation is to assign the value found in the constant table at the slot given by the second register, Kst(Bx), to the register table in the slot given by the first argument, R(A). “Bx” just means that because the opcode only has two arguments, the B register is extended and assigned more bits.
[Line 2] SETGLOBAL has the form “SETGLOBAL A Bx — Gbl[Kst(Bx)] := R(A).” It assigns a value to the global table using the key given by the constant table at the slot of the second argument. Because the second argument is 0 and the value of the constant table at 0 is “x,” it writes something to the global table using the key “x.” Whatever is in the register table at the slot given by the first argument is what’s being written, which the previous instruction loaded with the value 10.
Let’s look at a slightly more complicated example, “x = 10; y = x.” I’ll leave the manual execution of the code as an exercise for the reader. 🙂
Bytecode for function calls
Let’s look at the code generated for “foo(10):”
To execute function calls, the function must be loaded into the first register and arguments into subsequent ones. The semantics for “CALL A B C” are such that A holds the function, B is the number of arguments (actually, it’s the number of arguments +1, due to the way “…” is implemented), and C is the number of return values (again, it’s the number of return values +1, to handle multiple return values).
We’re familiar with the first two lines; they load a value into register table slot 0 and the value 10 into register table slot 1. The third line is what performs the function call, using the value in register A (register table slot 0, which was loaded with “foo”), with B specifying the number of arguments, and C the number of return values (remember, both B and C should have 1 added to their values). Before the function can be called, the VM also verifies that the value in R(A) is in fact callable.
Interlude — Metafunctions, metatables, and userdata
Lua has a mechanism that allows users to extend the functionality of tables by associating a metatable with an existing table. The metatable contains fallback methods that are invoked if a certain method or operation can’t be performed on the main table (see https://www.lua.org/pil/13.html for a thorough description).
For our purposes, the most relevant entries in the metatable are the “__index” and “__call” fields. __index is used when looking up an element in a table, so the code “local x = my_table[10]” would first call the __index method on my_table. If that failed, it would instead try to call __index on my_table’s metatable. __call is similarly used when you try to treat something as a function and call it “local x = foo(42),” for example
In order for Lua and C++ to interoperate, they need some way to be able to share functions and data. Lua facilitates this by providing a data type called UserData. UserData objects can be created in C++ land, and because they are native Lua data types, they can be adorned with metatables that allows Lua code to interact with them as if they were just regular Lua objects.
Member function calls
Okay, back to looking at some bytecode! This next example is a bit more interesting because it shows what happens when you have code like “foo:bar(10),” which is calling the bar method on the instance foo (an instance of the class Foo).
The new thing here is the self instruction [line 2], which we haven’t seen before. Self has the syntax “SELF A B C — R(A) := R(B)[RK(C)]; R(A+1) := R(B),” so let’s break this down. In the register table at slot R(A), it will place the result of looking up the table in register slot R(B) using the key in slot RK(C). It will also copy whatever was in slot R(B) into slot R(A+1), but more on this later. You might notice that the value of the C register is 257. This is valid because Lua is using RK(C) to look up the value, and RK will either use the register table or the constant table, depending on the value of 9:th bit. If it’s a 1, which it is in this case, then the constant table is used; otherwise, the lookup goes to the register table (after masking out the highest bit).
Line 3 places 10 in slot 2, and finally line 4 will execute the function call.
The SELF instruction serves two purposes. First, it looks for the “bar” method on the Foo class, and places it in R(A). Secondly, because foo is an instance method and we need the instance of the class that we’re invoking the method on when doing the call, it places this instance in R(A+1). If you’re familiar with classes in Python, then you might recognize the concept: methods are usually written as “def my_method(self, arg1, arg2..),” where self is the class instance.
We’ll need to dig into this a little deeper and take a look at what happens when the foo instance is a C++ object, represented in Lua as a UserData object.
The SELF call can be seen as a table lookup, i.e. Foo[“bar”] (capital Foo represents the class Foo, as opposed to foo, the instance), and we know that lookups will use the __index method. When the foo instance was created in C++ land, a metatable was associated with the instance, and the metatable had its __index field set to a piece of C++ code that will get called when __index is invoked.
Interlude — lua_State
When C/C++ gets called from Lua, the only data that gets passed is a lua_State object. This object contains everything related to the currently running Lua thread. The most important information in the state object is the Lua stack, which contains the function arguments (accessed via the lua_tointeger/tostring etc family of functions) and is also used to return values back to Lua.
In pseudo-C++, our __index function looks something like this:
Lots of internals are glossed over, but here’s the gist of it. Given that the UserData object passed as the first argument on the Lua stack, we’re able to find a descriptor that describes the actual C++ class, and via the descriptor we can see if this class has a method with the given name. If it does, a function pointer to a method invoker is pushed on the Lua stack, and we return success.
After this call, the Lua VM will place the rest of the arguments in the register table, and then call the function we returned from the metaIndex method, which will again call into C++, and land in the invoker function:
The methodInvoker also uses the ClassDescriptor, but this time it’s able to invoke the member function, and pop the correct arguments from the stack.
The home stretch!
Now that we can clearly see the two round trips from Lua to C++, we can try to figure out how to optimize this.
Our end goal is to do a single function call from Lua to C++ and have all the pieces we need on the Lua stack to be able to do method lookup and invocation at once. The problem seems to be that we have one register too few. When we call our combined lookup/invoker function, we want the Lua stack to look like [self, method name, arg1, arg2, …], but looking at SELF, we see that it uses its first slot for the result of looking up the method function and the second slot for storing the instance.
A key realization came when we looked at the way the __call metamethod worked. If an object has the __call metamethod, then before the _call function gets invoked, the object itself is pushed on the stack and all arguments are shifted up. By piggy-backing on this functionality, there was a way of getting “self” on the stack without having to explicitly store it in a register.
The second part involved getting the method name on the stack as well. For this, we had to be sneaky and alter the workings of the SELF opcode.
Remember that in the default case, SELF would try to find the member function and store this in R(A) together with the instance in R(A+1). We ended up skipping the lookup altogether and stored the actual object in R(A) and the method name in R(A+1).
If we now made sure that the object in R(A) had a __call metamethod, then we’d also end up pushing self on the stack. So, we’d have a stack that looked like [self, method name, args…] and did just a single call into C++. Perfect! Well, almost. 🙂
Before considering this done, we wanted to put some final polish on it. We didn’t want to overload the semantics of the __call metamethod, so instead we added a specific metamethod for this type of invocation—called __namecall—that was only available on UserData objects. We also modified the SELF opcode so it only uses the new semantics if the object has a __namecall metamethod.
The second thing we did was mostly make the new path and the old path able to share code easily. Instead of having the method-name as the second argument, we pushed it to the last argument. So, after it had been used to look up the method pointer, it could easily be popped off the stack and the stack looked like it did if the function had been invoked via the old path.

Conclusion
How much of an impact does this optimization have? Well, like most things in programming, the answer is “it depends.” For functions that are heavyweight—and you don’t call that often—you won’t see much of an improvement. But for smaller functions that you call often, the savings can be considerable.
People on the Developer Forum quickly noticed the appearance of this strange, new metamethod, and a table was presented that compared the speed of __namecall against both the old method of calling instance methods and against a workaround that developers had been using to optimize method calling:
The first loop uses the new __namecall code path, but because all the magic happens under the hood, there is no need for developers to change any existing code to benefit from the optimization.
The second loop emulates the old way of doing an instance method call; first doing a lookup to find the method and then invoking it.
And finally, the third loop shows a common optimization that developers were doing, where the method was first looked up, stored in a local variable, and then the variable was invoked.
The nice thing here is that it shows that with the __namecall optimization, it’s no longer necessary to explicitly cache instance functions, as it’s just as fast as the cached optimization, so the most straightforward code will also be the most performant.
Now that __namecall has been deployed, and we’re happy with the results we’re seeing, it’s time to turn our focus to memory usage, and see what we can do to improve the client in that area!
Functions C Programming
|
Lua can be embedded and extended[1] with code or applications written in other languages. Code and values in another language can be exposed to Lua and vice-versa. The following lists low and high level solutions for binding between Lua and other languages.
Lua C API
The most direct method to bind to Lua is with the Lua C API. The C API consists of two parts: the basic API (lua.h) provides the primitive functions for all interactions between C and Lua, while the auxiliary library (lauxlib.h) provides higher-level functions for some common tasks.[2]
- [The Lua 5.1 Reference Manual: The Application Program Interface] (5.1) describes Lua's native C API for calling Lua from C and vice-versa.
- See also Lua book [PIL2]. Or read about the C API online in the 1st edition of PIL: [PIL1 - The C API]
- An introductory video on embedding Lua in C++: [Embedding Lua in C++ #1]
- A tutorial for embedding Lua in C: [Embedding Lua in C]
Enabling API checking
By default, the Lua C API does almost no sanity checking of arguments passed to it. Passing incorrect stack indexes, for example, can result in segfaults or random data corruption. You should always enable API checking in any debug build. You can do this by compiling with the option -DLUA_USE_APICHECK. luaconf.h uses this C macro to define luai_apicheck to call assert() in various places (you can also edit this definition to do something possibly more useful).
Example
Some examples of using the C API can be found by examining the source code of Lua's own standard libraries (src/*lib.c}. For example, the math library (math.*) is implemented in the file src/lmathlib.c. The basic form of this file is outlined below. First we import various headers, including the C API (lua.h) and the auxiliary library (lauxlib.h):
Then various Lua functions implemented in C are defined. These all have the same signature, and arguments are passed via Lua's own stack. For example, the sin function is defined as follows. luaL_check_number() is used to check the correct type of the sin function argument. lua_pushnumber() is used to return the sine calculated. Note, the return value of the math_sin() function is the number of values returned (lua functions can return many values).
These functions are registered into Lua by building a table of function pointers and names and then calling luaL_register(). Constants pi and huge are set separately. This registration code is placed in a function named luaopen_math(), which can be called statically (e.g. from linit.c) or dynamically (via Lua's shared library loading mechanism via require).
Binding C/C++ with Lua
C
- [LuaAutoC] (5.2) - Automatically wrap C functions and structs at runtime.
- [LuaNativeObjects] (5.1) - A C bindings generator written in Lua. It turns C structs into objects.
- [luapi] (5.0) - a C API over the official Lua API.
- [CaLua] (5.0) - A way to bind C functions and structures to Lua, and work with C pointers, arrays and functions in Lua. (uses x86 assembly)
C Foreign Function Interfaces (FFI)
- [Alien] (5.1) - a foreign function interface (FFI) for Lua. An [FFI] lets Lua code call C functions directly without having to write C 'glue', so you can use Alien to write C extensions purely in Lua. (Wraps libffi)
- [C/Invoke for Lua] (5.1) - Use [C/Invoke] from Lua to call C libraries (DLLs, .so files) directly, like Microsoft's P/Invoke and Python's ctypes. (Similar to Alien)
- [The LuaJIT FFI] allows calling external C functions and using C data structures from Lua code. It parses plain C declarations and supports C99 plus some GCC/MSVC/C++ extensions.
- [luaffi] (5.1) - an implementation of LuaJIT FFI for Lua.
- [cffi-lua] (5.1, LuaJIT, 5.2, 5.3, 5.4) - Mostly compatible with the LuaJIT FFI (but integrates with new Lua versions), but portable (libffi based) and implemented from scratch.
C Inline
- [lua-tcc] (5.1) - Simple interface to TCC, a fast runtime C compiler by Fabrice Bellard, it allows a Lua script to compile C code and register it at runtime as Lua-callable C funcions. Intentionally limited to avoid TCC's bug with multi-environments, that would be too tempting in Lua.
- [Luatcc] (5.1) - another, more complete, Lua binding for libtcc, which is the core library of the [Tiny C Compiler]. It allows compiling and loading C code directly from Lua, includes the ability to load C modules directly from C source.
- InlineCee provides a similar approach, invoking other compilers out-of-process.
C++
Various C++ or C++ template bindings have been developed to simplify the process in C++:
- [MiniLua (5.3, 5.4)] - Minimal Lua interface for loading a lua-file and getting values into your C++-application.
- [Lua-Adapter] (5.3, 5.4) - Use this lightweight wrapper-/adapter-class as a simple 'interface' between Lua and C++.
- [CppLua] (5.0 & 5.1) - a C++ wrapper of the Lua API; handles class member functions.
- [LuaCppInterface] (5.2) - a C++ wrapper of the Lua API. Uses TMP to make calling/passing functions, handling coroutines and filling tables easy and type-safe.
- [sol2] (5.1, LuaJIT, 5.2 & 5.3) - a fast, powerful and easy C++14 wrapper for the API including support for table indexing, user-defined types, metamethods, coroutines and more.
- [sol] (5.2) - a C++11 easy to use and type safe wrapper of the Lua API.
- [Diluculum] (5.1) - A library that intends to make the coexistence of C++ and Lua more harmonious.
- [Tomaka17's lua wrapper] (5.2) - Simple bindings for Lua using C++11 supporting class and function registration, custom member functions, multiple return values, tables and more.
- [Luabind] (5.1 & [5.2]) - a template-based binding of C++ classes and functions which uses the Boost library. The library seems to be abandoned by the [original authors], but some more or less actively maintained [forks] exist, e.g. [3] or [4].
- [LuaBridge] (5.1 & 5.2) - lightweight, dependency-free, template-based library for exporting C++ classes/functions to Lua environments.
- [LuaBridge3] (5.1 & 5.2 & 5.3 & 5.4) - lightweight, dependency-free, template-based library for exporting C++ classes/functions to Lua environments, next generation with more feature and fixes.
- [SLB] (5.2) - Simple Lua Binder, a cross platform, small, easy to integrate, template-based library. Very similar to Luabind or boost-python but SLB doesn't require boost or any other dependency.
- [Luna] (4.0), LunaWrapper (5.1) and LunaFive (5.2) - clean, template-based method of binding a C++ class to Lua. See also [LTN5] and SimplerCppBinding.
- LunaWrap (5.2 & 5.3) - clean, template based way of pushing arbitrary types to and getting them from Lua, as well as a COMPILE-TIME 'proxy'-function ('int foo(lua_State*)') generator for C++ member functions!
- [MLuaBind] (5.1) - a template-based binding of C++ classes and functions which uses the Loki library.
- [MultiScript] (5.1) - a simple library that demonstrates Lua independent C++ interface to bind C++ classes and functions.
- [OOLua] (5.1, 5.2 & 5.3) - Cross platform template generator binding which has no dependencies.
- [Selene] (5.1, 5.2, 5.3) - Dead simple and intuitive C++11 bindings supporting class registration and functions.
- [Sweet Lua] (5.1) - a template-based binding of C++ classes and functions. (MSVC)
- [lux] - emits functions at compile time via C++ templates and argument overloading
- [nlua] - 'namespace lua' binding of C/C++ functions, table-like usage, templated based (no boost)
- [LuaWrapper] - A single header library that provides type-safe and intuitive functions such as luaW_to<T> and luaW_push<T> for arbitrary types, to make managing C++ classes with Lua simple.
- [Lutok] - Lightweight C++ API for Lua. Lutok provides provides thin C++ wrappers around the Lua C API to ease the interaction between C++ and Lua. These wrappers make intensive use of RAII to prevent resource leakage, expose C++-friendly data types, report errors by means of exceptions and ensure that the Lua stack is always left untouched in the face of errors. The library also provides a small subset of miscellaneous utility functions built on top of the wrappers.
- [integral] (5.1, LuaJIT, 5.2, 5.3, 5.4) - C++ library with no dependencies for creating Lua bindings.
- [lua-intf] (5.1, 5.2 & 5.3) - Pure C++11 API and binding for Lua (headers only), supports lua stack API, a higher level API that can refer lua object just like a C++ class object, and can also export C++ class and functions for lua script. The export binding supports custom C++ type, multiple return values, C++ shared pointer, in/out arguments, and can also make argument optional or with default value. The new version also comes with an optional Qt data type mapping (QString, QVariant, QByteArray, etc...).
- [LuaState] (5.1 & 5.2) - C++11 template library (clang, gcc and VS 12) no boost. Made to be really easy to use and as fast as possible. Lambda based bindings from Lua to C++.
- [Kaguya] (5.1 , 5.2 , 5.3) - C++03 with boost or C++11 template library.
- [Lua-Primer] (5.2, 5.3, Eris) - C++11 template library. Not only creates bindings to lua, but does it in a way that supports easy, seamless serialization using Lua Eris. See also [github] descriptions of eris.
- [Ponder] (5.3) Ponder is a C++ reflection API that can expose the API declared to Lua. Easy to use.
- [Automagical Bindings] Using C++11 templates to deduce C function arguments to automagically create wrappers to expose native C functions to lua code.
See also:
- DoItYourselfCppBinding - provides a few simple code fragments for helping Lua and C++ work together
- LuaGenPlusPlus - luagen++, a C++ header file to generate efficient sequences of Lua C API calls at compile-time via template metaprogramming techniques
- CppStreamChunkReader - lua_load chunk reader for any C++ std::istream (function)
- [A comparison of LuaBind, SWIG, OOLua, and toLua++] - One developer's attempt to find a good binding framework for use in a memory-constrained environment.
- [C++ Binding Benchmarks] - performance benchmarks for various C++:Lua bindings. [Github benchmark project here]
Calling Lua from C/C++
These frameworks and articles are one-way bindings: to call Lua functions from C/C++ passing arguments and getting return values.- [A Generic Call Function] (5.0) - from PiL uses a format string to call a global function with a variable number of arguments.
- [LuaGenericCall] (5.1) - uses code snippets and printf/scanf like format strings to support many types and features.
- [LuaClassBasedCall] (5.1) - uses code snippets along with C++ constructor overloads and templates, supports nearly all C++ types.
- [lua_icxx] (5.1) - embeds a Lua interpreter in a C++ application, using an OO API. See also SimpleLuaIcxxExample.
- SimpleLuaApiExample - example using the C API: the C program loads/runs a Lua script file, sets Lua variables and retrieves return value.
- CppLuaDataPassing - another more advanced example using regular C API to run a Lua script file with arguments.
- GettingValuesFromLua - explanation of how to get return values from
lua_dostring. - CallingLuaFromCpp - example to use the
Lunabinding (see above) to call Lua from C++.
Embedding Lua in C++
These frameworks are a little broader than the previous ones: they allow your C++ program full interaction with a Lua interpreter, but leave the task of extending Lua to other binding systems (SWIG, tolua++, and others).
- [lua_icxx]: (pronounced 'lua-ix') Lua interpreter for C++; call Lua functions and User Data (class) methods, use tables, create function sandboxes, use multiple return values, evaluate expressions and scripts, and more. The missing link for use of bindings like SWIG and tolua++.
Cpp Lua
Automatic binding generators
- [toLua] (5.2) - If there is a lot of information to bind then automating the process using a binding generator can help. toLua is one such tool. A package file is prepared, which is a cleaned up version of the C/C++ interface. Another advantage of this technique is that less work may be required between Lua versions if the Lua C API changes significantly.
- [tolua++] (5.1) - an extended version of tolua, with some extra features oriented to c++. See also CompilingToluappWithoutScons (compiling tolua++ without SCons).
- [CPB] (5.0) - A simple, fast, and powerful binding library for the Lua scripting language. It takes the information from the compilers symbols and generates binding code directly from it. (MSVC)
- [SWIG] (5.0/5.1) - Simplified Wrapper and Interface Generator, it can generate bindings between your C/C++ code and a variety of scripting languages (Python, Perl, Tcl/Tk, Ruby, ...), including Lua. A big advantage might be that *one* interface file, similar to that used in tolua/tolua++, is used for bindings to all languages supported by SWIG. See also the SWIG docs pertaining to Lua [5].
- [luna-gen] - lua binding-code generator that supports features such as properties, inheritance (both from lua and c++), namespace, enum, type-checking, c++ exception handling, adopt-policy, g++ and MSVS, operator overloading, user-configurable custum string and number/enum types and so on. Fast compilation and execution speed (much faster than luabind and SWIG), human-readable output codes, no boost dependency.
- [dub] - Uses Doxygen to parse C++ headers. Supports features such as properties, inheritance, type casting, Lua wrapping, enum, exception handling, operators, custom type binding, C++ template resolution, C++ callbacks with error handling, overloaded methods with runtime type resolution, etc. The generated code is optimized to be as fast as possible (return value optimization, inline objects, etc).
- [Ponder] - After declaring an API using Ponder it can be automatically exposed to Lua. Ponder is a C++ reflection system that also supports Lua binding, and XML/JSON serialisation.
Proxy wrapper for DLL
Function information can be exported from dynamically linked libraries. [FuBi] describes a method to call these functions from script (or RPC). This functionality can be used from Lua [6].
Miscellaneous
- [wxScript] (5.0) - A set of abstract classes to add script-interpreter support to your wxWidgets applications/libraries.
Other languages
Ada
- [Lua-Ada] (5.0) - Lua binding to Ada 95. (link broken)
- [lua-ada] (5.1) - Ada bindings to the Lua language (public domain) (link broken)
- [AdaCore ada-lua] (5.2) - Ada bindings to the Lua Language with generic packages to ease binding of Ada types to Lua
Bash Shell
The luabash tool is a dynamically loadable module for the bash shell that provides a bridge between the bash shell and the lua scripting language. This enables complex embedded code segments to be replaced with efficient lua code and the speed of shell scripts to be increased without the drastic need to rewrite existing code.
Basic
- [FreeBASIC] - A open-source BASIC compiler that comes with the Lua headers and libraries.
- [PBLua] (5.0.2) - a Purebasic library wrapping Lua 5.0.2. (deprecated)
- [PowerBLua] (5.0) - PowerBASIC include & source for wrapping Lua (work in progress).
- [BlitzMax] (5.1.2) - a BlitzMax module wrapping Lua 5.1.2 (note: the link currently points into this wiki (which is usually a bad idea in this list) but this will change as soon as the package has its own web site)
COBOL
- [OpenCOBOL] (5.1) - Using Lua with OpenCOBOL 1.1
- [OCLua] - Generated documentation from the OpenCOBOL interface source code
D
- [LuaD] (5.1) - Lua bindings and high-level interfaces for the D programming language.
- [DLua] (5.1) - Lua bindings for the D programming language.
Erlang
- [erlua] (5.1) - aims to enable seamless interoperability between Erlang and Lua.
- [erl-lua] (5.1) - an Erlang linked-in driver that allows embedding Lua into the Erlang VM.
- [erluna] (5.1) - Lua bindings for Erlang.
Fortran
- [Aotus] (5.3) - aims to enable seamless usage of Lua scripts for configuration of Fortran applications, uses the ISO-C-Binding.
- [f2k3-lua] - Interaction with Lua via the Fortran 2003 ISO-C-Binding.
Go
- [golua] (5.1) - Lua bindings for Go.
- [luar] (5.1) - a reflection layer on top of golua API providing a simplified way to publish go functions to a Lua VM..
- [go-lua-test](5.1) - Examples using various Lua bindings for Go
Haskell
- [HsLua] (5.1) - Scripting.Lua binding for Haskell.
Java
- [LuaJava] (5.1) - allows scripts written in Lua to manipulate components developed in Java (JNI to native Lua) and vice-versa.
- [JNLua] (5.2, 5.1) - another Java JNI <-> Lua bridge. Includes JSR 223 (Scripting for the Java Platform) provider.
- [jna-lua] - Java JNA <-> native Lua bridge.
- [java-lua] - Java JNI Lua bridge. Calls Lua from Java as well as Java callbacks from Lua
LabVIEW
- [Lua for LabVIEW] (5.0, 5.1) - embedding Lua into National Instruments LabVIEW software.
Objective-C
Writing Lua Functions C Program
- [LuaObjCBridge] (5.1) - calling Lua from Objective-C and vice-versa (MacOS X Cocoa).
- [LuaCore] (5.1) - a LuaObjCBridge-based framework, makes it easy to setup and run Lua scripts.
- [LuaCocoa] (5.1) - spiritual successor to LuaObjCBridge/LuaCore?, bridge between Lua & Obj-C, and uses Apple's BridgeSupport? to fill in remaining non-ObjC areas (e.g. structs, C functions, inline functions) to access all APIs on the platform. Also includes a command line tool suitable for writing AppleScript? in Lua via ScriptingBridge?. (Mac OS X).
- [iPhone Wax] (5.1) - a bridge between Lua and all the Objective-C/CocoaTouch classes.
- [Objective Lua] (5.1) - brings Objective-C-like syntax to Lua.
- [TLC] (LuaJIT 2) - A lightweight (Under 400 lines, pure Lua) bridge that exposes Objective-C objects&methods to Lua.
OCaml
- [ocaml-lua] (5.1.x) - calling Lua from OCaml and vice-versa (tested only in Linux, should work with OS X).
Pascal
- [VerySimple.Lua] (5.3) - Delphi XE5-XE7 Lua interface with OOP callback functions for Win32, Win64, Mac OS X, iOS and Android.
- [Freepascal bindings] (5.1 to 5.3.4) - Free Pascal bindings for the Lua library.
- [Pascal bindings] (5.1 to 5.3work1) - Pascal bindings for the Lua library, both for Delphi and Freepascal.
- [LuaPascal] (5.1) - Integrates Lua and Object Pascal languages. Allows Lua to manipulate components developed in Pascal/Delphi.
- [Lua4Delphi] (5.1) - Delphi and VCL Lua interface and Util functions.
- LuaDelphi (5.1) - calling Lua from Delphi/Pascal.
- [Lua4Delphi] (5.1) - for Delphi 2010 and XE.
- [THlua] (5.0) - Lua distribution for Delphi/Kylix/FreePascal. Includes header files, samples, some utils. For Windows, there are also LuaBinaries and project files for Visual Studio 6. Last updated in 2003.
- [Delphi-Lua] (5.0) - calling Lua from Delphi/Pascal.
- [DLua] (5.0) - calling Lua from Delphi/Pascal.
- [Free Pascal] Pascal units lua, lualib, lauxlib corresponding closely to the usual C API and axiliary library. See LuaInFreePascal.
Perl
- [LuaPerl] (5.1) - calling Perl (5.8 and 5.10 streams) from Lua.
- [Inline::Lua] (5.1) - calling Lua from Perl (inline).
- [Data::Lua] (5.1) - parse variables out of Lua code. Relies on Inline::Lua.
- [re::engine::Lua] (5.1) - supplies the Lua regular expression dialect for Perl.
PHP
- [LuaPhpExtension] (5.1) - PHP extension which allows embedding the Lua interpreter in a PHP application.
- [Nutria] (5.1) - PHP Standard Library written in Lua.
Python
Lua Call C
- LunaticPython[7] (5.1) - Lua/Python two-way bridge. Allows embedding of Lua interpreter in Python programs, and embedding of Python interpreter in Lua programs.
- [Lupa] (LuaJIT2)(5.1, 5.2, ?5.3) - Embedded Lua in Python. Allows two-way communication between Python and Lua code and tries to adhere to common behaviour on both sides.
- ffilupa [8] (5.2, 5.3) - A modern two-way bridge between Python and Lua. Integrate Lua into Python using CFFI as backend, which runs fast on both CPython and PyPy?. Inspired by Lupa.
R
- RClient [9] (LuaJIT) - LuaJIT client for Rserve which is used to host a (local or remote) R session toward which a connection is established. A library that allows to execute arbitrary R programs within LuaJIT.
- Lupa (python packaged mentioned above) + reticulate (package for and installed from CRAN within R: https://rstudio.github.io/reticulate/) - workaround that allows one to access Lua language and objects while in R session by passing through python session as an intermediary set up by the Reticulate. Best to review examples in both LunaticPython and Lupa to understand how to set up and use this workaround.
Ruby
- [RubyLuaBridge] (5.1) - calling Lua from Ruby (calling Ruby from Lua is planned)
- [rub-lua5] (5.0) - calling Lua from Ruby.
Tcl
- [ltcltk] (5.1) - a binding of Tcl and Tk for Lua.
- [LuaTclBridge] (5.0) - a Lua<->Tcl bridge.
- [TcLux] (4.0) - Tcl extension which embeds Lua into Tcl.
- See also [Lua] on Tcl.tk wiki.
Terra
[Terra] is a new low-level system programming language that is designed to interoperate seamlessly with the Lua programming language.
Like C, Terra is a simple, statically-typed, compiled language with manual memory management. But unlike C, it is designed from the beginning to interoperate with Lua. Terra functions are first-class Lua values created using the terra keyword. When needed they are JIT-compiled to machine code.
You can use Terra and Lua as:
A scripting-language with high-performance extensions. While the performance of Lua and other dynamic languages is always getting better, a low-level of abstraction gives you predictable control of performance when you need it.
A JIT compiler for your software's DSLs. Meta-program Terra using Lua. allows you to compile domain-specific languages (DSLs) written in Lua into high-performance Terra code. Embedding Terra-Lua programs in other software as a library allows you to add a JIT-compiler into your existing software.
A stand-alone low-level language. Terra was designed so that it can run independently from Lua. In fact, if your final program doesn’t need Lua, you can save Terra code into a .o file or executable. In this use-case, Lua serves as a powerful meta-programming language. You can think of it as a replacement for C++ template metaprogramming with better syntax and nicer properties.

Frameworks
CORBA
- [OiL] (5.1) - ORB in Lua ([CORBA])
Windows COM
- LuaCom - (5.1/5.0) Lua interface to Microsoft's Component Object Model (COM). Calling COM objects from Lua and implementing COM objects in Lua.
Windows .NET
- [dotLua] (5.0) - A .NET/CLI library, wrapping the Lua API.
- LuaInterface[10] (5.1) - a library for integration between the Lua language and Microsoft .NET platform's Common Language Runtime (CLR). Lua scripts can use it to instantiate CLR objects, access properties, call methods, and even handle events with Lua functions.
- [LuaNETInterface][11] (5.1) - a modification of LuaInterface to provide definition of Lua functions using attributes and loaded into the Lua engine using reflection.
- [NLua] (5.2) - a fork of LuaInterface which is active as of 2014
- [Eluant] (5.1) - a library with a similar purpose to LuaInterface/NLua, but fixing the memory management problems with LuaInterface/NLua. Active as of 2015.
- [LunaRoad] - Lua C API (v5.1, 5.2, 5.3, ...) for .NET / represents a flexible platform to work with Lua. Provides Lua interfaces, Lambda expressions, Dynamic features that can be used to generate new API-Layer automatically at runtime, etc. Active as of 2016.
Firefox
- [Moonshine] - embedded Lua environment for the Firefox web browser. Allows Firefox extensions to be developed in Lua rather than JavaScript. Implemented as an extension (XPI), written in XUL, JavaScript, and C++.
XML-RPC / SOAP
- See LuaXml.
See Also
- BindingEnumsToLua - a technique for synchronizing C enums with a Lua API
- EasyManualLibraryLoad - greatly simplifies manual loading (GetProcAddress? or dlsym) of Lua 5.1 shared library (.dll or .so)
- BoundScalarGlobalsOne/BoundScalarGlobalsTwo
edit · history
Last edited June 6, 2021 9:00 am GMT (diff)