Lua’s C API — Lua as a Configuration Language
With how robust Lua is when used as a standalone language, some people may be surprised to learn that Lua is actually intended to be a library for extending the functionality of C. In this post, I’ll cover one of the many ways in which Lua can extend the functionality of C by using it to configure some variables in C.
(Note, this post assumes that the reader knows the basics of programming in C)
Before we start using Lua to configure variables, we will need to cover the basics of how to use Lua in C. The first thing we need to add to a C program are the Lua headers.
These header files contain all of the functionality needed to use Lua in C, I’d personally suggest including all 3 by default. lua.h contains the core of Lua, and including it is required to do anything with Lua. lauxlib.h is the auxiliary library for Lua and contains some of the advanced functionality required by the Lua standard libraries, which can be opened by including the header lualib.h.
Now that you have the required headers, you will need to open Lua with the following line:
lua_State *L = luaL_newstate();
//In older versions of Lua, you would use lua_open()
This creates a pointer to an empty Lua Environment (A.K.A. State) called L. Before we can do anything useful with this environment, we need to define some functions to use by opening the Lua libraries.
//Again, in older versions, each Lua library is opened individually
Now that we have a usable Lua environment, we can start exchanging values between our C code and Lua. But how do we do that? The answer is with “The Stack”. The Stack can be populated with any Lua value, and then accessed by both the Lua environment and the C environment. When you want to send a value to Lua, you push the value onto The Stack and then call Lua to pop it off. When you want to get a value from Lua, you call Lua to push the value, and then pop it off in C. To keep the data types of these values consistent, we use different functions for pushing and pulling each datatype. One more major thing to note is that Lua can only push on and pop off The Stack, while C can operate anywhere on the stack’s structure.
When using Lua as a configuration language, we are mostly concerned about retrieving values from our Lua configuration file. The following code shows how to perform that task.
Our Lua Configuration File config.lua
width = 720
height = 360
Relevant code in our C Application windowDemo.c
//Open Lua Environment
lua_State *L = luaL_newstate();
//Open Lua Libraries
//Load the Lua config file in the Lua Environment
luaL_loadfile(L, “C:/users/ItsMe/Desktop/config.txt”) || lua_pcall(L, 0, 0, 0);
//Get the value of a Lua Global Variable called height, and push
//onto the stack.
//Notice that almost all of the C functions that interact with Lua
//will ask for the Lua environment as a parameter.
//Get the value at depth 2 of The Stack and parse it as an
int width = lua_tonumber(L, -2);
//I like to think of this stack as a pit that you’re dropping
//plates into, it makes the negative numbers a bit easier to
int height = lua_tonumber(L, -1);
//Close the Lua Environment and release resources.
Now that you have retrieved the values from your Lua configuration file, you can use them elsewhere in your C application.
The final thing we need to cover is the extra compiler options required to compile a C application that uses the Lua Libraries. This tends to vary from system to system and compiler to compiler, but the statement that worked for me was this:
gcc –o luaWin windowDemo.c –I<path to Lua header files> L<path to Lua libraries> -llua
Replace the bracketed portions above with the paths to those files on your computer and this should work, provided you are using the GNU C Compiler. Other compilers will work in very similar ways.
I hope this post was useful in learning how to use Lua as a C configuration language. I hope you can find some great uses for this in your own applications.