Running a Lua 5.2 script from C++

Lua is an extensible programming language to extend other programming languages — called host languages. This is extremely powerful for many reasons. My favorite is that

It allows to change the behavior of a compiled program without having to recompile it.

Unfortunately, I have not found many tutorials on the net regarding the basic embedding of Lua 5.2 — which is a bit different from 5.1, 5.0 and 4.X — in C++, including these topics:

  1. How to run a Lua script from C++
  2. How to pass information from Lua to C++ and vice-versa
  3. How to call C++ functions from Lua
  4. How to dynamically link libraries of C functions to Lua
  5. How to implement a simple class in Lua
  6. How to pass objects from C++ to Lua and vice-versa

This is just the transcription of my personal notes about the first topic. Hopefully, in the future I will also transcript the notes I have taken regarding the rest of topics. Most of the information has been taken from the Lua Wiki sample code and updated (if needed) using the Lua 5.2 reference manual.

I am using Lua version 5.2.1 downloaded from its official page and compiled in Microsoft Visual C++ Express 2010. I am not covering the compilation process of Lua — it is well documented online — nor the meaning of the Lua code beyond its basic behavior.

Running a Lua script from C++

This is the most basic action you can do with embedded Lua in a C++ program. Imagine you have the typical Hello World program in Lua, something like

-- Simple Hello World Lua program
print('Hello World!')

and you want to run it from inside a simple C++ program. The procedure is the following:

  1. Create a Lua state — like a Lua virtual machine in which our script will be running.
  2. Load the needed Lua libraries to run the script.
  3. Run the Lua script.
  4. Close the Lua state.

The project must link to the Lua libraries, that have been compiled previously, and must have access to the Lua header directory, since we will be including the <lua.hpp> file. We also assume that the C++ executable is generated in the same directory as the Lua script and that the script is called <helloworld.lua>.

The full code will look like:

#include <lua.hpp>

int main(int argc, char* argv[])
{
    // create new Lua state
    lua_State *lua_state;
    lua_state = luaL_newstate();

    // load Lua libraries
    static const luaL_Reg lualibs[] =
    {
        { "base", luaopen_base },
        { NULL, NULL}
    };

    const luaL_Reg *lib = lualibs;
    for(; lib->func != NULL; lib++)
    {
        lib->func(lua_state);
        lua_settop(lua_state, 0);
    }

    // run the Lua script
    luaL_dofile(lua_state, "helloworld.lua");

    // close the Lua state
    lua_close(lua_state);
}

The output of the program is just what we expect:

Detailed explanation

Let’s check the code by pieces. The first piece is to create the new Lua state:

    // create new Lua state
    lua_State *lua_state;
    lua_state = luaL_newstate();

There is no mystery to it. The only step is to store in a pointer the newly created Lua state returned by luaL_newstate(). Afterwards we can use that pointer to refer to the Lua state.

The second piece is to load the needed libraries. This is a bit more tricky. Every Lua library — even the ones generated by yourself — are opened by a C++ function and stored in the Lua state as a global table with a given name. Therefore, our first step is to define the name and opening functions for the desired libraries. Since our hello-world script is so simple, only the base Lua library is needed. We define “base” as the name of the base library, which is opened by the luaopen_base() function.

    // load Lua libraries
    static const luaL_Reg lualibs[] =
    {
        { "base", luaopen_base },
        { NULL, NULL}
    };

Then, we load every selected library by calling its loading function with our Lua state pointer. The lua_settop() sentence just ensures that we discard any variables that may be populated into the Lua stack.

    const luaL_Reg *lib = lualibs;
    for(; lib->func != NULL; lib++)
    {
        lib->func(lua_state);
        lua_settop(lua_state, 0);
    }

The third piece is to run our script which is self-explained in this code:

    // run the Lua script
    luaL_dofile(lua_state, "helloworld.lua");

You only have to provide the Lua state in which you want the script running and the filename — with full path if it is not in the same directory of your C++ executable — of the Lua script.

The last piece is to close the Lua state:

    // close the Lua state
    lua_close(lua_state);

This will remove any memory used by the Lua state — except for some tables in rare cases.

And that is it!

That is the one of the most simple examples of embedding Lua into C++ programs. Stay tuned for further, more complicated examples. Read the next tutorial!

About

View all posts by

9 thoughts on “Running a Lua 5.2 script from C++

  1. This is all really great info; thanks for sharing.

    Could you show how you would handle catching exceptions in your C++ code? Reading luaconf.h has not been particularly illuminating.

Leave a Reply

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