Embedding Lua (Part 1)

Introduction

Lua is a versatile and lightweight scripting language. It is designed to be embedded in a host application and provides a C API for communication between Lua and the host program. Although Lua doesn’t support a programming paradigm by itself, it can be used as an object-oriented language, or as a functional one depending on your needs. This post will serve as a short introduction to embedding Lua to a C++ host application.

Embedding Lua

Below is a pretty simple example of embedding Lua in a c++ host application:

The code is pretty much self-explanatory; create a new lua_State, load Lua libraries on that state, execute some Lua code on the state and finally closed the state. As you can see, the lua_State is a central aspect of the API. You can create multiple states per program and all API methods take one as an argument. After executing the above snippet you should see “Hello from Lua!” printed on the console.

You may have noticed that some functions start with lua_ and others with luaL_. All basic Lua functions are prefixed with lua_. All luaL_ prefixed functions belong to the Lua Auxiliary library, which builds upon the basic Lua API and provides higher-level functions for some common tasks.

There’s not much going on on the above example. Lua only starts becoming useful when you are able to interact with it. So let’s see how this is done.

Calling a Lua function from C++

 Let’s say that we have the following code in a calculator.lua file:

The c++ code to load and interact with the above Lua code is:

Now, some explaining. Lua uses a virtual stack for all interactions with C/C++ code. Each and every element in this stack is a Lua value (one of nil, boolean, number, string, function, userdata, thread, or table). The Lua C API provides functions in order to push and pop values into and from the stack.

Calling a C function from Lua

Let’s say that we want to expose to Lua a function that accepts one number as a parameter, and returns two numbers; the square root of the parameter and it’s power of 2.

Each C functions that gets called by Lua is assigned its own stack. Initially, that stack will contain the function’s arguments. After the function returns, any return values must be on the top of that stack. The called function must have the signature: (int) (lua_State*).

Roundup

The Lua stack mechanic can become cumbersome very quickly. On the next post of the series we’ll use SWIG to generate code that hide’s the stack and allows for more direct C++/Lua communication.

Leave a Reply

Your email address will not be published. Required fields are marked *