Binding Code To Lua

lua-users home
wiki

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]

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):

#define LUA_LIB
#include "lua.h"
#include "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).

static int math_sin (lua_State *L) {
  lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
  return 1;
}

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).

static const luaL_Reg mathlib[] = {
{"abs",   math_abs},
{"cos",   math_cos},
{"sin",   math_sin},
... etc...rest of table not included, but make sure you finish of with:
{NULL, NULL}
};

/*
** Open math library
*/
LUALIB_API int luaopen_math (lua_State *L) {
  luaL_register(L, LUA_MATHLIBNAME, mathlib);
  lua_pushnumber(L, PI);
  lua_setfield(L, -2, "pi");
  lua_pushnumber(L, HUGE_VAL);
  lua_setfield(L, -2, "huge");
  return 1;
}

Binding C/C++ with Lua

C

C Foreign Function Interfaces (FFI)

C Inline

C++

Various C++ or C++ template bindings have been developed to simplify the process in C++:

See also:

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.

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).

Automatic binding generators

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

Other languages

Ada

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

COBOL

D

Erlang

Fortran

Go

Haskell

Java

LabVIEW

Objective-C

OCaml

Pascal

Perl

PHP

Python

R

Ruby

Tcl

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

Windows COM

Windows .NET

Firefox

XML-RPC / SOAP

See Also


RecentChanges · preferences
edit · history
Last edited June 14, 2023 9:00 pm GMT (diff)