Luabridge Call Lua Function From C++

wiki
  • In this tutorial we go over calling Lua functions from C.Twitter: https://twitter.com/KarmaKilledTC.
  • Aside from those definitions, the code in that test case is self-contained. On Mon, Apr 7, 2014 at 1:38 AM, Andrew Starks wrote: On Monday, April 7, 2014, Moose wrote: Hi allI am making moderate progress integrating Lua into my C environment. After trying many.

Lua Call C++


The implementation allows C code to access Lua objects such as numbers or strings, but more importantly to access things like tables and their values. Using this class makes idioms like calling Lua functions simple and clean. LuaBridge tries to be efficient as possible when creating the 'glue' that exposes C data and functions.

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 Luna binding (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++.

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

  • [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

  • 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
RecentChanges · preferences
edit · history
Last edited June 6, 2021 9:00 am GMT (diff)

Troubleshooters.Comand Code Corner Present


From a running Cprogram, you can call a Lua script. The C program can pass arguments tothe Lua script, and the Lua script can pass back a return. The Luascript can serve to initialize the C program, or the Lua script caninstall a callback routine in the C program.
Calling a Lua script from a C program can be daunting without the rightinformation. Different computers have different names and locations forlibraries and include files, and it's difficult to figure out what'scausing compile/link problems.
Further complicating things is that with every major version of Lua,the method of calling Lua from C changes. Much documentation on theInternet is specific to Lua 5.0, and won't work on 5.1. Likewise, thisdocumentation is specific to 5.1, and when 5.2 comes out (it's alpharight now), the documentation on this page won't work on the newversion.
The purpose of this document is to make it easy for you to do simple Lua calls from C programs.
A typical interaction from a C program to a Lua 5.1 script looks something like this:
  • Create a Lua state variable
  • Load Lua libraries
  • Load but don't run the Lua script file
  • Priming script run to create script's global vars
  • Pass all arguments to the Lua script on the stack
  • Run the loaded Lua script
  • Retrieve the return from the Lua script
  • Close the Lua state variable

Create a Lua state variable
lua_State *L;
L = luaL_newstate();
Load Lua libraries
luaL_openlibs(L);
Load but don't run the Lua script file
luaL_loadfile(L, 'script.lua')
Priming run of the loaded Lua script
to create the script's global variables

Pass all arguments to the Lua script on the stack
Various routines, too many to name.
Run the loaded Lua script

Retrieve the return from the Lua script
Various pops and stack calls
Close the Lua state variable
lua_close(L);

Header Files

Always put these three header files at the top of any C program calling Lua:

Compiling and Linking

Nothing is tougher than compiling and linking your first C to Luaprogram. There are way too many variables, it seems like everything's ablack box, and you run around changing things trial and error, crossingyour fingers.
But there's a method to the madness, and this subsection explains it.If you know all the content of this section, try not to be offended orinsulted -- the extra info is for those who don't know it yet.
Here's a typical command to compile it:
Let's break that down:

Your systems C compilation command. Could be cc, or gcc, or something else.

Show all warnings. You might choose not to insert this until all other errors and warnings have been fixed.

The name of the finished executable.

The name of the C file to compile.

Every C compiler checks for include files in certain places. But often lua.h, liblua.h and lauxlua.h aren't in those places, so you need to tell the compiler where to find them.

Every C compiler checks for libraries to link in certainplaces. But often the Lua libraries are elsewhere, so you need to tellthe compiler where to find them.

Link in the Lua library. The way you name this library in the compiler's -l option requires some thought and research, which will be explained later in this subsection.

Link in the math library (often not necessary)

The Process of Finding the Right Compile Command

Finding the right compile command is a process that looks something like this:
  1. Try to compile, no link, no -Wall, no -I. You might get lucky.
  2. Find the location of the Lua include files.
  3. Using that location, compile, no link, no -Wall.
  4. Compile, no link, use -Wall.
  5. Find the location and filenames of the Lua library files.
  6. Using the location and filenames, compile and link.
  7. Test the Executable.
Luabridge Call Lua Function From C++

Step 1: Try to compile, no link, no -Wall, no -I

Do this:
Notice that the -c means 'compile only, do not link'. Sometimes it'snot all that clear whether an error or warning comes from compile orlink, but it's very clear if you only compile. If the preceding commanddoesn't error out, skip to step 4. However, in my case it errored out:
On to step 2..

Step 2: Find the location of the Lua include files

The three Ubiquitous Lua include files are lua.h, lauxlib.h, and lualib.h. Use your Linux box's locate command to find lua.h after running updatedb to make sure that locate finds everything. Make sure that the directory with lua.h also contains lauxlib.h, and lualib.h.
Obviously the directory you want is /usr/include/lua5.1. Now see if that directory contains the other two:
OK, that's it. You know you need to add -I /usr/include/lua5.1 to the command.

Step 3: Using that location, compile, no link, no -Wall

In my case the preceding worked:
If it hadn't worked, and you'd included all three header files in hello.c, and you're sure you got the additional include directory right, suspect wrong code in hello.c itself. If it doesn't produce errors or warnings, go on to the next step..

Step 4: Compile, no link, use -Wall

In my case, the preceding produced no errors or warnings:
If it produces warnings, try your best to fix them. Warnings are oftena sign of problems that rear their ugly head a week after deployment.Call
Once you have no errors or warnings, go on to the next step..

Step 5: Find the location and filenames of the Lua library files

First a word about how the -l compiler option works. The -loption assumes every library file starts with 'lib'. Therefore, insteadof making you type -lliblua, it makes you type -llua and then out ofthe goodness of its heart prepends lib before the lua. For instance, if you put -llua, that means that it searches for a file called liblua.a or liblua.o or liblua.so, etc. So you need to find the liblua.* files. Do it as follows:
Here's the partial result:
See the ones called liblua5.1.*? Those are the Lua libraries on my computer. So we have a pretty good idea that the -l argument should be lua5.1.We also know that they're located in /usr/lib, which probably isalready on the C compiler's library path, so we probably don't need a -L compiler option. If these files had been in /usr/lib/lua, we'd have needed an -L option.

Step 6: Using the location and filenames, compile and link

This step differs from step 4 in two ways:
  1. We remove the -c so that it will attempt to link
  2. We add -llua5.1
Here we go..
It worked. If it hadn't, we'd have been forced to troubleshoot.

Step 7: Test the Executable

So let's run it:
You haven't seen the code for hello.c and helloscript.lua yet, but take it from me that the preceding output was exactly what it was supposed to do.

Summary

Here's how you build a C program that runs a Lua script:
Create a Lua state variable
lua_State *L;
L = luaL_newstate();
Load Lua libraries
luaL_openlibs(L);
Load but don't run the Lua script file
luaL_loadfile(L, 'script.lua')
Priming run of the loaded Lua script
to create the script's global variables

Pass all arguments to the Lua script on the stack
Various routines, too many to name.
Run the loaded Lua script

Retrieve the return from the Lua script
Various pops and stack calls
Close the Lua state variable
lua_close(L);

You always include lua.h, lauxlib.h and lualib.h. You use the Linux locate command to find where those files are, and use that location in a -I compiler option. You always link with liblua, and you use locate commands to find where that library is, and use it in the -l compiler option and if its location isn't in a normal library directory, put its directory in a -L compiler option.
Getting Lua-calling C programs to compile and link can be difficult andfrustrating. To limit the difficulty and frustration, use this process:
  1. Try to compile, no link, no -Wall, no -I. You might get lucky.
  2. Find the location of the Lua include files.
  3. Using that location, compile, no link, no -Wall.
  4. Compile, no link, use -Wall.
  5. Find the location and filenames of the Lua library files.
  6. Using the location and filenames, compile and link.
  7. Test the Executable.
Now it's time for your Hello World program.
Let's start with the one line Lua script itself. Call it helloscript.lua:
That's it, one line. Notice it doesn't have the #!/usr/bin/lua line on top. It doesn't have to because the C Lua interface has a built-in Lua interpreter which the lua_pcall() function invokes automatically.
So if you run the C program and see the text 'This is coming from lua.' you know you've succeded.
Next let's review the steps covered in the Anatomy of a Lua Call article:
Create a Lua state variable
lua_State *L;
L = luaL_newstate();
Load Lua libraries
luaL_openlibs(L);
Load but don't run the Lua script file
luaL_loadfile(L, 'script.lua')
Priming run of the loaded Lua script
to create the script's global variables

Pass all arguments to the Lua script on the stack
Various routines, too many to name.
Run the loaded Lua script

Retrieve the return from the Lua script
Various pops and stack calls
Close the Lua state variable
lua_close(L);

Your Hello World program will implement all the above, in that same order, EXCEPT:
  • Priming run of the loaded Lua script
  • Passing arguments to the Lua script
  • Retrieving the return from the Lua script
Also, we'll put in an error handler function called bail() just to make the code look more concise. We'll call this program hello.c. Here's the code:
As you can see, it's pretty much the same as discussed in the list ofsteps, except no args are passed into Lua and no return variables arepassed out.
Remembering the discussion from the Anatomy of a Lua Call article, compile and link it, troubleshooting as necessary. Here's how it compiles and links on my computer:
Do what's needed til it compiles no errors, no warnings, with the -Wall compiler option. Then run it. It should look like this:
Study the program. Everything should be pretty obvious except lua_pcall(),and that will be discussed later. Once you've gotten output like thepreceding and really understand what's going on (with the possibleexception of lua_pcall() details), it's time to continue..
Remember the program from the Hello World article did everything except these:
  • Priming run of the loaded Lua script
  • Passing arguments to the Lua script
  • Retrieving the return from the Lua script
In this article we'll do all these things. By the time you're doneconstructing the code in this article, you'll have passedarguments, from Lua to a C subroutine, and have received backreturn values.
Tourist Trap Alert

All over the Internet, including on some of the Lua project's owndocumentation, you'll see hints basically telling you that to call a Csubroutine you do:
lua_getglobals(L, 'subroutine_name')
push_args_to_subroutine
if(lua_pcall(L, num_of_args, num_of_returns, 0)
error_routine();

These Internet instructions say nothing about doing a priming lua_pcall(), and if you do not do a priming lua_pcall(), you'll get an error message something like this:
attempt to call a nil value
If you get the preceding error message and don't know it's caused by lack of a priming lua_pcall() (or priming lua_call() or priming dofile()),you're about to have several hours or maybe even days of frustration.Mailing list threads old and new about this error basically tell youRTFM or RTFW, but of course we locals know it was reading the web thatgot you into this problem in the first place.
I saw one guy who took the opportunity to tell the asker 'I'm trying tohelp you help yourself but you won't take the help, so now I'm puttingyou on my list of people I won't help.' All for what we locals know wasprobably a simple lack of a priming run THAT SEEMS NOT TO BE DOCUMENTEDANYWHERE!
Before calling a function in a Lua script, do that priming run first!!!!!!

OK, let's start by calling a specific function in a Lua script. Create this callfuncscript.lua file:
Now, noting that most of it is from the Hello World article you've already read, create the following callfunc.c:
The only change over the Hello World code is a priming run and pushing the tellme() Lua function via the lua_getglobal() call. Note that the second lua_pcall() still has its second arg, number_of_args, of 0, because you're not sending an argument to the Lua function tellme().

Arguments and Return Value

The previous part of this article was written primarily to make sure you knew that to call a specific Lua function, you need to push that function on the stack with lua_getglobal(), and that you make sure to do a priming run, because without it you're in for hours of frustrating debugging and detour ridden RTFW.

There are several pieces of example code on the net showing the passingof arguments to entire Lua scripts rather than functions, and thosewhole Lua scripts returning arguments. They do this by, within C,setting a global variable to be used in Lua. I've chosen not toreproduce these techniques here because:
  1. In my opinion the internals of such code is a little hard to understand
  2. I never liked global variables in the first place.
  3. Multiple args to the main Lua script require multiple global variables such code becomes quite muddled
  4. Functions are built from the ground up to accept a series of arguments.

Now take your callfuncscript.lua file and add a function called square, so the whole script looks like this:
And change callfunc.c to look like the following:
Be sure to notice the following things in the preceding C code:
  • Even though two functions are called, only one priming run isneeded. Each Lua script requires only one priming run in order tocreate its globals so its functions are visible to the C program.
  • In order to fully pass an integer into callfuncscript.lua'ssquare() function and receive the function's return, the lua_pcall()'snargs argument must be 1 (one argument passed in) and its nreturnsargument must be 1 (1 argument passed back). If nargs is 0 you'll getthe dreaded ' attempt to call a number value' error, while if nreturnsis 0 it will always return 0. So remember, this lua_pcall() is lua_pcall(L, 1, 1, 0).

A use case that happens often is the passing of tables to and from Luafunctions. How is that handled? There are a few idioms you see over andover again to make it happen. Before discussing the idioms, here's thecode:

The Lua Program

Here's the Lua program. As you can see, function tweaktable receives atable argument, converts all values to upper case, counts the values,and puts all that info in a new table that's returned.

The C Program

The C program is the same as all the others except stacking argumentsto Lua is a little different, and recovering the table passed back fromLua is a little different. The Lua tweaktable() function takes a tableas its one and only argument and passes back one table. It passes backa completely different table so there's absolutely no question of thechanges being made by reference to the args rather than passback.
Start by looking and running the code, and then we'll discuss some of the idioms that make it work..
The preceding code yields the following output:

Table Argument Passing Idioms

You start by placing an empty table on the stack, and build it it onekey/value pair at a time. The way you place an empty table on the stackis with the following command:
The way you give the now stacked table a key/value pair is like this:
You can do that over and over again with different key/value pairs. Each time the numeric argument to lua_settable() is -3 because lua_settablepops the two stack items above it after incorporating them in itstable, so at its end it's at the same level that it was before youstacked the key and value.
Note that you might be stacking things other than literals. Here are the many pushers available:
  • lua_pushboolean
  • lua_pushcclosure
  • lua_pushcfunction
  • lua_pushfstring
  • lua_pushinteger
  • lua_pushlightuserdata
  • lua_pushliteral
  • lua_pushlstring
  • lua_pushnil
  • lua_pushnumber
  • lua_pushstring
  • lua_pushthread
  • lua_pushvalue
  • lua_pushvfstring

Other functions push or at least put things on the stack, including:
In spite of what it sounds like, this function actually puts the function corresponding to the fcnname argument on the top of the stack.
This function puts an empty table at the top of the stack.
Thisfunction replaces the previous key with the new one, and then pushesthe new value on top of that. You need to do a pop to stay even.

And here are some poppers:
This pops off the stack, number levels.
This pops twice after assigning the key/value pair in the top two stack positions to the table at level -level.

Table Return Passing Idioms

When a Lua function called from C returns ends it puts its returnvalues on the stack. When a return value is a table, retrieving thetable's elements isn't obvious. Assuming the Lua function returned onlyone thing and that thing is a table, then that table is at the stack'stop when it comes back to C. Here's how you access it:

Luabridge Call Lua Function From C++ C

In the preceding, you push a nil in order to make sure lua_next()starts with the first item. The reason you use -2 as an arg tolua_next() is because after you push the nil, the returned table is thesecond item down on the stack. On each iteration, lua_next() replacesthe existing key with the next one, and then pushes the next value ontop of it. Therefore to keep things in place you need one pop per cycle.

Luabridge Call Lua Function From C++ Using


On every iteration immediately after lua_next(), the top of the stack is the new value, one down from that is the new key, and one down from that is the table.

[ Troubleshooters.com Code Corner Email Steve Litt]

Copyright(C) 2011 by Steve Litt -- Legal