In this short tutorial I'll show how to run Lua programs from C and C++ and how to expose functions to them. It's easy!
Update: The code in this post has been updated for Lua 5.2.4. I haven't checked if the Lua 5.3 C API is backwards-compatible with 5.2. All the code here is available on GitHub.
The first program will just create a Lua state object and exit. It will be a
hybrid between C and C++. Since the two languages must include different files,
we need to discern between them by checking for the existence of the
Notice that I'm being explicit about which version of Lua I'm using in the
code. If you trust that the Lua developers care about compatibility, you can
#include <lua.hpp> and so on directly.
The purpose of the program is just to make sure that we can compile, link and run it without errors.
You need to let the compiler know where it can find the include files and the
Lua shared library. The include files are usually located in
/usr/local/include and the library files in
/usr/local/lib. Search your
system directories if needed. To compile the above program, pass the
You may swap out
llvm-g++, or just
c++, depending on your
compiler. If you're using a C compiler, use
llvm-gcc — but
remember to rename the file to
Now try to run the program to make sure it doesn't segfault:
This one worked just fine.
The next step is to execute Lua programs from your C or C++ code. We'll create the Lua state object as above, load a file from disk and execute it.
Put this into
You can reuse the compilation arguments from above:
Let's test this with some Lua programs. The first one prints the Lua version and exits.
You may want to double-check that it works by running
lua hello.lua. It may
not be important for this trivial program, but can become important when you
try more advanced ones.
Now try it with
You can even run bytecode-compiled programs:
We should also check that the error handling works. Put some garbage in a file
error.lua, for example
Running it produces
It gets very interesting when Lua programs call back to your C or C++
functions. We'll create a function called
howdy that prints its input
arguments and returns the integer 123.
To be on the safe side, we'll declare C linkage for the function in the C++
version of the program. This has to do with name mangling,
but in this case, it really doesn't matter: Lua just receives a pointer to a
function, and that's that. But if you start using dynamic loading of shared
dlsym, this will be an issue. So let's do it
correct from the start.
Copy the above program into a file called
callback.cpp and add the
We have to pass the address of this function to Lua along with a name. Put the
following line somewhere between the call to
Create a test program called
Compile and test it
I told you it was easy!
Read the Lua C API
Reference. You've learned enough now to get going with it. Did you see my
note about clearing the stack in
howdy? You may want to investigate that.
Find out how to integrate Lua closures with your C functions.
If you want to hide or catch console output from Lua, you need to figure that
out as well. I once did it by trapping
io.write(); I copied its code from
lualib.c and changed
io_write to point to my own function. There is
probably a better way to do it, though. Doing so is useful for things like game
or smart pointers to manage resources like
I also strongly recommend to try out LuaJIT. Calling into your functions there is even easier, using LuaJIT's foreign function library. I'll write a blog post on how to do that as well. In short, just create ordinary C functions, compile as a shared library, copy their signatures into pure Lua source code and hook them up with LuaJIT's FFI library.
LuaJIT runs between 10-20 and up to 135 times faster than interpreted Lua, so it's definitely worth it.