Open In App

Integrating Lua in C++

Lua is a high-level, multi-paradigm programming language, mainly used in embedded applications as well as powerful scripting support for existing products. For Example Scripting enhancement of an NGINX, HA Proxy, Wireshark, etc. Another major area where Lua had found application is the game engine frameworks.

Why Use Lua?

There is the various reason for choosing Lua to provide the scripting support:



Despite all the above advantages, Lua provides a very low-level C API which requires the developer to learn the internals of the Lua engine before he can use it in the applications. However, this has changed with the Lua Cpp library.

LuaCpp: It is a lightweight wrapper for Lua C APIs that provides access to the Lua library of two levels i.e., Accesses through high-level APIs that are hiding the complexity of the C APIs and the engine, and access to the Lua low-level APIs.



How to install Lua?

The LuaCpp can be installed as a system-wide library, or as a sub-module of your exiting project. Run the below command to install the LuaCpp in ubuntu.

=> git clone https://github.com/jordanvrtanoski/luacpp.git

=> cd luacpp
=> mkdir build
=> cd build

=> cmake ../Source
=> make -j `nproc`

=> make install

Once the library is installed, build the file as follows:

=> gcc hello.cpp -I /usr/local/include/LuaCpp -I /usr/include/lua5.3/ -lluacpp -llua5.3 -lstdc++ -o hello

Output the file as:

=> hello

Below is the same program to illustrate the same:




// C++ program to illustrate the use of
// LuaCpp library
#include <LuaCpp.hpp>
#include <iostream>
using namespace LuaCpp::Registry;
using namespace std;
 
// Driver Code
int main(int argc, char** argv)
{
 
    cout << "Hi from C++, this is a demo"
         << " how LuaCpp can be used\n";
 
    LuaContext lua;
 
    // The simplest way is to use
    // CompileStringAndRun method
    try {
 
        lua.CompileStringAndRun(
            "print('The fastest way to "
            "start using lua in "
            "a project')");
    }
 
    catch (std::runtime_error& e) {
        std::cout << e.what()
                  << '\n';
    }
}

Output:

Passing data from C++ to Lua and back:

The example is showing us how to compile and execute Lua code snippet from C++. However, without the ability to pass data from C++ to Lua, and back from Lua to C++, there are not many real-life cases that can be addressed by this pattern.

LuaCpp arrives prepared to establish the bridge between the two execution environments wilt as little as possible knowledge of the internal working of Lua, as well as with minimal code. Let’s improve the “Hello World” example by adding a variable that will be shared by both execution environments. This introduces a “String” variable called “world” and populates it with a value from the C++ context. Inside the Lua context, update the value of the variable, and upon return to the C++ context and print the value of the variable.

Below is the program to illustrate the same:




// C++ program to illustrate the
// above approach
#include <LuaCpp.hpp>
#include <iostream>
using namespace LuaCpp;
using namespace LuaCpp::Registry;
using namespace LuaCpp::Engine;
using namespace std;
 
// Driver Code
int main(int argc, char** argv)
{
    LuaContext ctx;
 
    shared_ptr<Engine::LuaTString> str = make_shared<Engine::LuaTString>(
        "world from C++!");
 
  ctx.AddGlobalVariable("world", str));
  ctx.CompileString("test",
                    "print('Hello '..world)"
                    "world = 'world from lua!'");
 
  // Try Catch Block
  try {
      ctx.Run("test");
  }
  catch (runtime_error& e) {
      cout << e.what() << '\n';
  }
 
  cout << "Hello "
       << str->getValue() << "\n";
}

Output:

The context allows passing multiple variables from the C++ scope to Lua scope and vice versa. The above pattern allows for adding the scripting support to the C++ project for the majority of the cases. The simple 4-step process is:

Supported Lua Types:

The LuaCpp provides the following types of variables that can be passed between the C++ and Lua context:

Conclusion:

Adding scripting support to the existing C++ project brings huge flexibility and configurability to the developed application. Although Lua C APIs are not very complex, they still demand from the developer to fully understand the inner workings of the Lua virtual machine. As covered in this article, LuaCpp is abstracting all of this complexity and provides an interface that is very familiar to the C++ developer. 


Article Tags :