State of the union (or: Who's got a VM?)The first thing we have to be aware of is that lua is essentially a state machine. Additionally, lua is a virtual machine. We'll come back to that in a bit (hopefully). Anyway, once you have initialized your programs interface to lua, you can send lua commands through a lua function called lua_dostring. But I'm really starting to get ahead of myself. Let's back this up a bit and start from the top of the interpreter. First and foremost, pretty much every function in lua deals with a lua state. This essentially defines the current state of the lua interpreter; it keeps track of the functions, global variables and additional interpreter related information in this structure. You create a lua state with a call to lua_open. This function looks like this: lua_State *lua_open (int initialStackSize); If you want, you can think of lua_State as a handle to the current instance of the lua interpreter. It's a fair analogy. So, it we get a non-null lua_State we know that lua managed to initialize correctly. That's good, and it means we can now do stuff with lua. But we can only do a small set of things with lua by default. More on this shortly. Let's get some code in place that we can use as a starting point. lua_open() is defined in lua.h (you can find that in lua's include directory). So, we should be able to compile the following code snippet as a win32 console application: #include <stdio.h> #include <lua.h> int main(int argc, char* argv[ ]) { lua_State* luaVM = lua_open(0); if (NULL == luaVM) { printf("Error Initializing lua\n"); return -1; } return 0; } Unfortunately, this won't work. More to the point, it won't link. It's a pretty simple problem, but one of those niggling little issues you get when you're dealing with Open Source projects. Essentially, lua was written to be ANSI C compliant. Please note: I said ANSI C. Notice that all the files in the lua library all end with the "c" extension. This essentially means that the way the compiler mangles the names of all the functions in lua is based on the C calling convention. This is different that how C++ handles function naming. It's not terribly hard to fix, it just is annoying more than anything else. To fix it, simply wrap the #include <lua.h> and any other include statement that references lua library functionality inside of: extern "C" { … } So, what we end up with is: #include <stdio.h> extern "C" { #include <lua.h> } int main(int argc, char* argv[ ]) { lua_State* luaVM = lua_open(0); if (NULL == luaVM) { printf("Error Initializing lua\n"); return -1; } return 0; } Easily, this is a candidate for inclusion in its own header file. Compilation at this stage will produce an exe that runs. It does nothing, but it runs. So, at this point, you're probably thinking that if we have an 'open' statement, we are going to need a close statement. And you'd be correct. lua_close() essentially closes a state that was opened with lua_open(). Very straight forward. The format of lua_close() looks like this: void lua_close (lua_State *openState); We can finish off our code above by adding this to the application: #include <stdio.h> extern "C" { #include <lua.h> } int main(int argc, char* argv[ ]) { lua_State* luaVM = lua_open(0); if (NULL == luaVM) { printf("Error Initializing lua\n"); return -1; } // Do stuff with lua code. lua_close( luaVM ); return 0; } And voila, we have a completely useless bit of lua. But, we have, in its infancy, a completely embedded scripting system in our app. |
|