In this short tutorial I'll show how to run Lua programs from C and C++ and howto expose functions to them. It's easy!
Update: The code in this post has been updated for Lua 5.2.4. I haven'tchecked if the Lua 5.3 C API is backwards-compatible with 5.2. All the codehere is available on GitHub.
26 – Calling C from Lua. One of the basic means for extending Lua is for the application to register new C functions into Lua. When we say that Lua can call C functions, this does not mean that Lua can call any C function. (There are packages that allow Lua to call any C function, but they are neither portable nor robust.). For this part of the tutorial series, we will be discussing on how to interact with classes and objects, both in Lua and C. Using a C class in Lua. First off, let’s bind a simple C class so that we can use the class in our lua code. You can name your class anything, but I’m going to use something simple, ‘CppObject’. In this short tutorial I'll show how to run Lua programs from C and C and how to expose functions to them. 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 ahybrid 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 thecode. If you trust that the Lua developers care about compatibility, you canjust
#include <lua.hpp> and so on directly.
The purpose of the program is just to make sure that we can compile, link andrun it without errors.
You need to let the compiler know where it can find the include files and theLua shared library. The include files are usually located in
/usr/local/include and the library files in
/usr/local/lib. Search yoursystem directories if needed. To compile the above program, pass thedirectories with
You may swap out
llvm-g++, or just
c++, depending on yourcompiler. If you're using a C compiler, use
llvm-gcc — butremember to rename the file to
Now try to run the program to make sure it doesn't segfault:
This one worked just fine.
Executing Lua programs from a host
The next step is to execute Lua programs from your C or C++ code. We'll createthe Lua state object as above, load a file from disk and execute it.
Lua C Function
Put this into
You can reuse the compilation arguments from above:
Running Lua programs
Let's test this with some Lua programs. The first one prints the Lua versionand exits.
You may want to double-check that it works by running
lua hello.lua. It maynot be important for this trivial program, but can become important when youtry 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 filecalled
error.lua, for example
Running it produces
Calling C functions from Lua
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 inputarguments 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 afunction, and that's that. But if you start using dynamic loading of sharedlibraries through
dlsym, this will be an issue. So let's do itcorrect 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 thefollowing line somewhere between the call to
Create a test program called
Compile and test it
I told you it was easy!
Call Lua From C Example
Read the Lua C APIReference. You've learned enough now to get going with it. Did you see mynote about clearing the stack in
howdy? You may want to investigate that.
Lua Example Code
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 thatout 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 isprobably a better way to do it, though. Doing so is useful for things like gameprogramming.
Use RAIIor 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 foreignfunction library. I'll write a blog post on how todo that as well. In short, just create ordinary C functions, compile as ashared library, copy their signatures into pure Lua source code and hook themup with LuaJIT's FFIlibrary.
LuaJIT runs between 10-20 and up to 135 times faster than interpreted Lua, soit's definitely worth it.
This is a simple introductory example of how to interface to Lua from C. The C program loads a Lua script file, sets some Lua variables, runs the Lua script, and reads back the return value. The below example works with Lua 5.3.
First, create the below Lua script file and save it as 'script.lua'. This script will dump to the screen the contents of a table named 'foo' (that will be created from the C program) and return the sum of this table's components.
In order to access it from C, we could hack a little program that would construct the table, pass it to the script, and get the returned value. Create a C program called 'test.c' as follows:
It's now time to compile it. Keep in mind you'll need to link against -llua (Lua) possibly -lm (the math library). In the system I wrote this simple test, 'cc -o test test.c -I/usr/local/include -L/usr/local/lib -llua -lm' generated the binary as expected. On another system (OpenSuse? 11.4, gcc4.7) -ldl was also needed to resolve undefined references to 'dlopen' etc.
Finally, running the test you should get something like:
That should demonstrate how the basic API works and how values are passed between C and Lua.
For more, see [Lua API Demo]. It is a module designed for the Lua interpreter that allows you to set up a fake Lua state with a stack, call Lua API functions, and observe their effect on the stack.RecentChanges · preferences
edit · history
Last edited March 2, 2018 6:09 am GMT (diff)