I don't claim to be a professional in using lua c api. These tutorials should be considered as an introduction to it and not as an in-depth guide.
I. Installation
To install lua api on a Debian derivative type following line into the terminal (tested on Ubuntu 12.04):
$ sudo apt-get install liblua5.1-0-dev
(don't enter the '$' symbol)
If you're using another distro then consult its package management system. If lua development files are not in the repositories then you can still download and build lua.
To do so, download the sources from here. (Note that this tutorial covers only the installation of lua 5.1)
Extract the archive, open up the terminal and cd to the directory that has been extracted from the archive. After that you can simply type:
$ make linux
The build process could take some time, depending on your machine. To install the libraries and headers to a public directory (either /usr/local/lib/ + /usr/local/include/ or /usr/include/ + /usr/lib/) enter:
$ sudo make install
This step makes many things simpler since you don't have to specify the library/header search directories explicitly.
II. Hello, Lua
In this part of the tutorial we will expose a C string that contains "Hello, Lua" to Lua and pass it to Lua's print function. So, here's the complete source code first:
// main.cpp
#include "lua5.1/lua.hpp"
int main()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
lua_pushstring(L, "Hello, Lua");
lua_setglobal(L, "hello");
luaL_dostring(L, "print(hello)");
lua_close(L);
return 0;
}
You can build the source by calling:
$ g++ main.cpp -llua5.1 -o lua_app
So, the first line of code includes lua headers (for C++). Note: you may want to use '<' and '>' instead of the double quotes, and that would probably be the right thing to do. The only reason why I picked double quotes in the include statement is because they seem to make less problems with the syntax highlighter.
The following line creates a new lua state.
lua_State* L = luaL_newstate();
Lua states are instances of the lua interpreter. An application can have multiple unrelated states. They don't share anything, so if you execute a script that defines a variable 'a' in one state then other states still won't know anything about it. Most functions of the lua api require a pointer to a lua state as their first argument.
We make the lua standard library available to our state using the following call.
luaL_openlibs(L);
Now we come to the part where we create our variable. Be careful, this part could be a little bit tricky. So, to exchange values between lua and c/c++ we use the so called stack (that has nothing to do with the normal stack of a c/c++ program). It works like that: if we want to make a value available in lua then we put it onto the stack and then it can be used from within lua and if lua calls a C function and passes some arguments to it, then they also land on the stack and then you have to "extract" them from there in order to be able to use them in your C code. (You'll see how it works in the next tutorial when we bind a C++ function to Lua
So in our case we want to "export" a string value to lua so we call lua_pushstring function and give it the pointer to our state (so it knows which lua instance will get the string) and the string itself ("Hello, Lua" in this case). We'll that's good, now we've got a string in lua, but how do we access it? The question is answered in the next line: we call the lua_setglobal function. This function creates a global variable (called "hello" in this case) and assigns a value from the stack to it. So these two lines of C++ code...
lua_pushstring(L, "Hello, Lua"); lua_setglobal(L, "hello");
...are the same as this line in lua:
hello = "Hello, Lua"However, how does the function know which value to assign to the variable if there are multiple values on the stack? Well, the lua_setglobal function assumes that the value we want to assign is on the top of the stack (and our string is on the top since we haven't pushed anything else). After assigning the value to the global variable the string is removed from stack, so it's perfectly clear again.
The call to luaL_dostring in the next line expects a string with some lua code and the state that will execute it. At this point we also could have used luaL_dofile, if we had a lua script. (creating a separate script for one line of code is however a bit overkill, if you ask me).
The lua code in the string calls lua's print-function (which wouldn't be available if we hadn't called luaL_openlibs, because it's a part of lua's standard library) and lets it print the string we created in c++.
The call to lua_close, closes the specified lua state and frees all resources associated with it.
As you may have noticed the API functions have 2 kinds of prefixes: "lua_" and "luaL_". What's the difference? Well, "lua_"-functions are functions of the "naked" lua API, while "luaL_"-functions are handy functions provided by the lua auxiliary library that is there to make our life easier by providing out-of-the-box functionality for common stuff that we would otherwise have to implement by ourselves.
So, that was the first lua c api tutorial and also a brief demonstration of it. In the next tutorial we will extend lua with functions from C/C++.
I hope you could follow me and good night!
Keine Kommentare:
Kommentar veröffentlichen