LUA DOCUMENTATION. This project is a 2D C engine with Lua on top as a scripting language.The project provided uses a Hearthstone like PVE card game. There are 2 parts of Lua integration, the C Lua wrapper and the Lua code used to create the cards. Lua is a dynamic language while c is a typed language. This part contains one of the most important practices in Lua programming which I discovered pretty recently and felt dumb afterwards because for the last two years I’ve been doing stuff wrong. Today I’m going to talk about storing Lua tables and variables in scripts. Storing data in Lua is great.
- C++ Lua Scripting Tutorial
- Lua C++ Programming
- Lua Scripting C++
- C++ Lua Game Scripting
- C++ Lua Scripting Interview
Lua has a very simple C API. You can run Lua code and access lua objects from C. Similarly, you can access C functions and libraries from Lua. In this post, we’ll primarily look at how to expose C functions to lua.
Let’s start off with the installation of lua. You can install lua using system package managers as
C++ Lua Scripting Tutorial
You can also build lua from source. However, you have to build lua as a shared library and this can be a bit tricky.
Communication between lua and C is held through stacks with each element in stack representing lua value (nil, number, string, etc.).
For example, a C wrapped function
c_swap is called in lua as:
In C, you will receive arguments in a stack as
You will then read the arguments from the stack as (indexing for this stack starts with 1 like in lua):
This is actually unsafe because these calls will fail if value in the stack at the specified index is not a number. Following code uses auxiliary library
lauxlib.h and is safer; it will raise errors instead of segfaulting.
Then, you will process the arguments and push the results to stack.
Stack will now look like
Since you need to communicate the number of return value to lua, you will
return 2. Lua will then know that top 2 values in the stack are the returned values.
The stack we’ve described is not global. Each function has its own stack.
Let’s put all this together into
main() function illustrates how to run lua code from C.
And build and execute as If you have installed lua with apt-get, build using
gcc main.c -o swap -llua5.2 -I/usr/include/lua5.2/
which should print
In the above code, you’ve not really used lua interpretor; you’ve run the lua code in C itself.You might rather want to create a module which you can load into a lua interpretor using
To do this, you’ll have to register your functions by creating a array of
luaL_Reg and a function
Let’s do this right away by editing
main.c. We will also add additional
This code works only for lua 5.2. For lua 5.1, please use
luaL_register(L, 'mylib', mylib); instead of
Create a loadable
.so file with
If you have installed lua with apt-get, build using
gcc main.c -shared -o mylib.so -fPIC -llua5.2 -I/usr/include/lua5.2/
You can now load this module in lua.
Now, you should be able to wrap any C library by writing a lua wrapper.We still have some caveats:
- We will have to write a wrapping function for each of the functions in your C library to ‘parse’ the arguments(
luaL_checknumberetc.). This is repetitive and can be a potential source for bugs.
- C doesn’t have classes. What if your library is in C++? You cannot easily wrap classes like above. You will have to mess with metatables and so on.
A solution to both of these is to use Swig. Swig allows you to wrap C/C++ classes/functions into many languages like python, lua, java quite easily. In a later post, we will see how to use swig and wrap a simple library.
EDIT: Part 2
Long time without posting, busy at work, family, etc.
Today I decided to write a bit on Lua and how to integrate it with C++.
Lua is a scripting language with an emphasis on being easily embeddable. Lua isused as the scripting language in Photoshop CS, and World of Warcraft, forexample. So if you are looking into adding scriptability to your C or C++applications Lua is quite suited for the task.
In order to learn Lua (both the language itself and how to embed it into yourapp) I recommend you Programming in Luaby one of the Luaauthors.
You can find tons of tutorials on how to get started with Lua. So I will focushere on how to integrate with C++. Most of the sources I’ve found about Lua -C++ integrations take the approach of frameworks to automatically wrap yourobjects/classes to be usable from within Lua. I find this approach confusing, Ithink it’s better to learn how to do it manually, and that’s what I will dohere.
Step 0. Compile Lua itself
Download Lua 5.2.1 and compile it. Usually it enough with
make macosx or
make linux. That will generate
liblua.a, the library that we will link to.
Step 1. Create a simple host app
We need a simple host app. Our host app will simply setup Lua and run a scriptfrom it. This script will have access to a
std::queue from the host app. Thiswill illustrate how you can share objects with the Lua part. Later we will takea more complex example.
Let’s start with the basic skeleton of a lua environment with somecommunication with its host:
LUAHOME that should point to the directory containing both
liblua.a and the
The samplehost application
The Lua script
The code explained step by step:
That creates a
lua_State loads the standard libs in it and also loads the code in
Adding variables from C++ into Lua
Then it sets a global variable in Lua from C++ code using
lua_setglobal. Ifyou don’t know what are the
lua_pushxxxx and the Lua stack, etc. I recomentthat you take a look at the Lua Reference Manual and Programming in Lua.More or less Lua and the C++ communicate through the stack that livesin
lua_State and there is bunch of function to manipulate that stack. So inorder to set a global in Lua from C++ you must push the value into the stackand call
lua_setglobal that will pop the value in the stack and assign it tothe identifier provided inside the Lua environment.
After setting the global
cppvar it executes the loaded chunk of code (that is in the stack) with
lua_pcall. The Lua code is able to read and print the value of
cppvar. The lua code will also set a new global
luavar that we will access from C++.
Reading a Lua variable from C++To get luavar from C++, we must first use
lua_getglobalthat will put the value associated with the identifier into the top of the stack and the
Lua C++ Programmingwill transform whatever it’s at the top of the stack into a double (well a
luaNumber) and then we can use that double in our C++ code to print it.
Calling a Lua function from C++
The example won’t be complete without function calling so that’s the next step.Calling a Lua function from C++ it’s quite easy. Function in Lua are firstclass values, so that means that it’s just a like reading a any other value.
lua_getglobal will get the value and put it on the stack and then we push thefunction arguments into the stack and use
lua_pcall to call the function(that is the stack). The returned value from the function will be pushed in thestack and that’s were the C++ code will get it,
lua_tostring and then it willremove from the stack with
Calling a C++ function from Lua
The other way around it’s more complex. You can’t just call any function fromLua. It has to has a special signature
lua_CFunction, that is,
typedef int(*lua_CFunction) (lua_State *L) a function that returns an int and takes a
lua_State. This special funciton will communicate with Lua via the lua stackthat resides in the
lua_State parameter. The return value of the functiontell lua how many value the function has pushed into the stack as result valuesfor the function call.
Lua Scripting C++
So to make the function accesible from Lua, you create push the function intothe stack with
lua_pushcfunction and bind it to an identifier in lua with
lua_setglobal. Then lua code will be able to invoke this function like anyother function. In the example I call the
myfunction (which is lua code) and
myfunction in turn invokes
cppfunction which is “bound” to C++
l_cppfunction. Ah, I almost forgot.
l_cppfunction is declared as
extern'C' telling the compiler to provide C linkage for this function so it can becalled from a C library like Lua is.
C++ Lua Game Scripting
Free Lua resources
lua_close will free all resources held by the
C++ Lua Scripting Interview
I will leave the part on how to wrap C++ class objects inLua for a later post because Idon’t want to make this post too long. Hopefully I’ll post it tomorrow.