1. Lua C++ Call Member Function
  2. C++ Lua Calling Member Functions
  3. C++ Lua Calling Member Function Example
  4. C++ Lua Calling Member Function Examples

The FFI library allows calling external C functions andusing C data structures from pure Lua code.

Lua C++ Call Member Function

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. For the latest version of Lua, there are 2 functions to call to register a function, these are luapushclosure, and luasetglobal. You may wish to wrap those two calls in a single function, but in my case I created a table of functions to map, and iterated this calling those functions. Tomaka17's lua wrapper (5.2) - Simple bindings for Lua using C11 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 FFI library largely obviates the need to write tedious manualLua/C bindings in C. No need to learn a separate binding language— it parses plain C declarations! These can becut-n-pasted from C header files or reference manuals. It's up tothe task of binding large libraries without the need for dealing withfragile binding generators.

The FFI library is tightly integrated into LuaJIT (it's not availableas a separate module). The code generated by the JIT-compiler foraccesses to C data structures from Lua code is on par with thecode a C compiler would generate. Calls to C functions canbe inlined in JIT-compiled code, unlike calls to functions bound viathe classic Lua/C API.

This page gives a short introduction to the usage of the FFI library.Please use the FFI sub-topics in the navigation bar to learn more.

Motivating Example: Calling External C Functions

It's really easy to call an external C library function:

Lua c++ call member function

So, let's pick that apart:

Load the FFI library.

Add a C declarationfor the function. The part inside the double-brackets (in green) isjust standard C syntax.

Call the namedC function — Yes, it's that simple!

Actually, what goes on behind the scenes is far from simple: ③ makes use of the standardC library namespace ffi.C. Indexing this namespace witha symbol name ('printf') automatically binds it to thestandard C library. The result is a special kind of object which,when called, runs the printf function. The arguments passedto this function are automatically converted from Lua objects to thecorresponding C types.

Ok, so maybe the use of printf() wasn't such a spectacularexample. You could have done that with io.write() andstring.format(), too. But you get the idea ...

So here's something to pop up a message box on Windows:

Bing! Again, that was far too easy, no?

Compare this with the effort required to bind that function using theclassic Lua/C API: create an extra C file, add a C functionthat retrieves and checks the argument types passed from Lua and callsthe actual C function, add a list of module functions and theirnames, add a luaopen_* function and register all modulefunctions, compile and link it into a shared library (DLL), move it tothe proper path, add Lua code that loads the module aaaand ... finallycall the binding function. Phew!

Motivating Example: Using C Data Structures

The FFI library allows you to create and access C datastructures. Of course the main use for this is for interfacing withC functions. But they can be used stand-alone, too.

Lua

Lua is built upon high-level data types. They are flexible, extensibleand dynamic. That's why we all love Lua so much. Alas, this can beinefficient for certain tasks, where you'd really want a low-leveldata type. E.g. a large array of a fixed structure needs to beimplemented with a big table holding lots of tiny tables. This imposesboth a substantial memory overhead as well as a performance overhead.

Here's a sketch of a library that operates on color images plus asimple benchmark. First, the plain Lua version:

This creates a table with 160.000 pixels, each of which is a tableholding four number values in the range of 0-255. First an image witha green ramp is created (1D for simplicity), then the image isconverted to greyscale 1000 times. Yes, that's silly, but I was inneed of a simple example ...

And here's the FFI version. The modified parts have been marked inbold:

Ok, so that wasn't too difficult:

First, load the FFIlibrary and declare the low-level data type. Here we choose astruct which holds four byte fields, one for each componentof a 4x8 bit RGBA pixel.

Creating the datastructure with ffi.new() is straightforward — the'?' is a placeholder for the number of elements of avariable-length array.

C arrays arezero-based, so the indexes have to run from 0 ton-1. One might want to allocate one more element instead tosimplify converting legacy code.

Since ffi.new()zero-fills the array by default, we only need to set the green and thealpha fields.

The calls tomath.floor() can be omitted here, because floating-pointnumbers are already truncated towards zero when converting them to aninteger. This happens implicitly when the number is stored in thefields of each pixel.

C++ Lua Calling Member Functions

Now let's have a look at the impact of the changes: first, memoryconsumption for the image is down from 22 Megabytes to640 Kilobytes (400*400*4 bytes). That's a factor of 35x less! So,yes, tables do have a noticeable overhead. BTW: The original programwould consume 40 Megabytes in plain Lua (on x64).

Next, performance: the pure Lua version runs in 9.57 seconds (52.9seconds with the Lua interpreter) and the FFI version runs in 0.48seconds on my machine (YMMV). That's a factor of 20x faster (110xfaster than the Lua interpreter).

C++ Lua Calling Member Function

C++ Lua Calling Member Function Example

The avid reader may notice that converting the pure Lua version overto use array indexes for the colors ([1] instead of.red, [2] instead of .green etc.) ought tobe more compact and faster. This is certainly true (by a factor of~1.7x). Switching to a struct-of-arrays would help, too.

C++ Lua Calling Member Function Examples

However the resulting code would be less idiomatic and rathererror-prone. And it still doesn't get even close to the performance ofthe FFI version of the code. Also, high-level data structures cannotbe easily passed to other C functions, especially I/O functions,without undue conversion penalties.