Tag Archives: software

Integrating Lua Into a C++ Project

Scope – Why Integrate Lua?

Lua is a scripting language that can be embedded into, or used to to control, conventional C and C++ programs. From what I have read, it seems that the typical use case is to create a piece of software, primarily in Lua. Then C components are used to either extending Lua functionality, or replace performance sensitive pieces of code.

Lots of boxes

Sometimes software fits together likes this.

I have several potential uses for a scripting language. At my day job I administer a chat server and I am working on a game engine at my 2nd job. Both of these pieces of software are written in C++ and could benefit from some dynamic scripting, the kind that Lua can provide. Depending on implementation details this could allow me to run scripts that the were made after the software was initially compiled. For the chat server I could get more detailed information about who is available and when, easily recover logs, and do other things I haven’t thought of yet all without having to alter the C++ code. For the game engine I could add dynamic functionality to levels, provide and administrative command prompt (like some shooters), and do other things I haven’t thought of yet all without having to alter the C++ code. I know it sounds like I have no idea what I am planning, but I do have some definite plans in both projects. It feels like adding a scripting language provides so much flexibility; I feel like I need an Ikea bookshelf, but I am showing up with all the tools from a wood shop and a CNC mill.

Many proponents of Lua feel that the bulk of a software project should be made in Lua, and C should only be used to optimise performance. However, these are both large pieces of software. Strictly controlling them through Lua is not practical. Rather, I will have them call Lua scripts at certain times. These scripts can in turn follow their own dynamic logic and use various components of the original software. This means that we will need to tightly integrate Lua, tell Lua about the already existing C++ functionality, and create a mechanism for calling Lua scripts. Then it will have to be done in the other project too.

I figured I should make a sample project and document what I am doing for future reference. I will make the most minimal implementation of “A C++ program which calls a Lua script, which calls a C++ function in the original program”. Here is what I did, why I did it and how I overcame the problem doing it caused. I go through this project chronologically detailing the major errors I made, so that as many people as possible might benefit from solutions I helped find.

The Tools

You will need a C++ compiler and an IDE, I use GCC (MinGW on windows, yes I did this on two machines to verify consistency) and Code::Blocks. I used the latest version (mingw-get-inst-20111118.exe at the time of this writing) of MinGW on windows, and GCC 4.5.2 from the Ubuntu apt-get repository. I had to include the folder “c:\mingw\bin\” in my system PATH on windows. Any newer version of these tools should work well, windows only users may wish visual studio to use instead. Any decent compiler should work. I won’t go into details about these, you should know roughly how to use these before reading this.

I used SWIG to help generate the Lua bindings for my C++ code. On windows I used Swigwin 2.0.4 and on Ubuntu I installed the swig2.0 package which installed swig 2.0.4. Since there is no windows installer you will need to make the swig executable and lib folder available in the system PATH somewhere. I placed both in the directory “c:\windows”, but you could just as easy put them anywhere and add that to the system PATH. Ubuntu automatically configured this for me.

To create the build configuration I use CMake. I used CMake 2.8.3 and 2.8.6, however since no advanced features where used you can probably get by with 2.6 or newer, if you already have something installed. On windows I got the installer cmake.org and again I use the Ubuntu repo to install the package I needed “cmake-gui”. If you want to familiarize yourself with the cmake command language, you can visit the CMake Docs page.

You will also want a decent text editor and file archiver. I can’t recommend Notepad++ and 7-zip enough, they did exactly what I needed them to on windows, and they did it swiftly and accurately. Ubuntu already comes with a decent text editor and file archiver.

For reference here is a single line command to install all the tools on Ubuntu:

sudo apt-get install g++ codeblocks cmake-gui swig2.0

I did not intend for that last section to seem like a glowing praise for Ubuntu, but it really is mind boggling how much easier it is to do really complex things on Linux than on windows. Things like adherence to standards, a sane security model, package repositories and other simple design idioms can really take an operating system far.

Starting the Mini Project

I started by creating a tiny C++ project in CMake. I made a basic source and header file, and I made a folder to put the Lua source in. You can get the unmodified Lua source from www.lua.org/source. I used the 5.1 version of Lua because SWIG doesn’t support 5.2 yet. I made a fairly basic CMakeLists.txt for Lua and one for my source that includes the Lua project. Here is a tarball of Lua 5.1 with my CMakeLists.txt built in. Consider all the parts I added to be available in the public domain, all the parts from PUC-Rio (the makers of Lua) are still under the MIT original license.

I arranged the project so that Lua would be built as a static library with mostly its own configuration. Here is the file system hierarchy for this whole little project, it looked like this in the beginning and didn’t really change,with the exception of the swig generated file:

  • CMakeLists.txt
  • Lua/
    • CMakeLists.txt
    • lua5.1
    • test.h
      • COPYRIGHT
      • doc/
        • Stuff …
      • etc/
        • Stuff …
      • HISTORY
      • INSTALL
      • Makefile
      • MANIFEST
      • README
      • src/
        • lua.h
        • lua.c
        • and other stuff we need to compile …
      • test/
        • Stuff …
  • luabinding.cpp – Created by swig
  • test.cpp
  • test.h

Round 1 – Simple Mistakes

Here are the faulty files that I started with. Since I didn’t know what would and wouldn’t work, I just tried something. I will explain why these are faulty as the article continues, but note that these are incomplete and makes no attempt to perform the whole task of using Lua to run a script, that runs a C++ function. The C++ function that Lua will eventually run is included for the purposes of creating the Lua bindings.

Faulty Original – CMakeLists.txt:

# Set up some some basic variables
cmake_minimum_required (VERSION 2.8)
project (LuaTests)

message ("${PROJECT_NAME} – Begin")

# Can used to build this and Lua with any compiler flags. The flag for debug builds is included
set(CommonBuildFlags ${CMAKE_CXX_FLAGS_DEBUG})
add_definitions( ${CommonBuildFlags} )

# Some common variables I set up in many of my CMake Projects
set (${PROJECT_NAME}_ROOT_DIR "${${PROJECT_NAME}_SOURCE_DIR}/")
set (${PROJECT_NAME}_SOURCE_DIR "${${PROJECT_NAME}_SOURCE_DIR}/")
message ( STATUS "Base Directory for ${PROJECT_NAME}: ${${PROJECT_NAME}_ROOT_DIR}")

set (${PROJECT_NAME}_BINARY_DIR "${${PROJECT_NAME}_BINARY_DIR}/bin/")
set (PROJECT_BINARY_DIR "${${PROJECT_NAME}_BINARY_DIR}")
set (LIBRARY_OUTPUT_PATH "${${PROJECT_NAME}_BINARY_DIR}")

message ( STATUS "Putting complete binaries in: ${${PROJECT_NAME}_BINARY_DIR}")

# An array for the source files

set(${PROJECT_NAME}_sources
   "test.cpp"
   "test.h"
   "luabinding.cpp"
)

#Tell compiler where to find lua binary and header
link_directories( "${LuaTests_BINARY_DIR}/libs/" )
include_directories(
   "${${PROJECT_NAME}_SOURCE_DIR}/Lua/lua-5.2.0/src/"
   "${${PROJECT_NAME}_SOURCE_DIR}/Lua/lua5.1/src/"
)

# Include the Lua project
add_subdirectory (Lua)

# Define the output executable and what it relies on and must link against.
add_executable(${PROJECT_NAME} ${${PROJECT_NAME}_sources})
add_dependencies( ${PROJECT_NAME} Lua )
target_link_libraries( ${PROJECT_NAME} lua)

message ( STATUS "Putting lua binaries in: ${LIBRARY_OUTPUT_PATH}")

message ("${PROJECT_NAME} – End")

Faulty Original – test.cpp:

#include "test.h"
#include "lua.h" // Lua Core
#include <iostream>

int main (int argc, char** argv)
{
   std::cout << "This program will attempt to call a lua script that in turn runs a c function. This was output via cout streaming in c++ " << std::endl;
   lua_State *State; // create a pointer to Track the Lua State
   State = luaL_newstate(); // Create a Lua State
   lua_close(State); // Close the Lua state

   //once I get this simple test to compile I will try calling a lua script here

   //Once that script is being called I will try to call void PrintHello()

   return 0;
}

void PrintHello()
{
   std::cout << "Hello world! From PrintHello()" << std::endl;
}

Faulty Original – test.h:

#ifdef SWIG
   %{
      #include "test.h"
   %}
   %module testscripting
#endif

void PrintHello();

SWIG is a tool that reads the source code in a C++ and generates Lua bindings. Bindings are the function that a Lua script can call that in turn call C functions. I had it read my test source and generate the bindings in file “luabinding.cpp”. This can be done with the following commands if you have the tools as suggested above.

On Ubuntu Linux:

swig2.0 -c++ -v -lua -importall -o luabinding.cpp test.h

On windows:

swig -c++ -v -lua -importall -o luabinding.cpp test.h

After running SWIG I would get errors when trying to build against Lua 5.2 I would errors similar to the following:

||=== LuaTests, LuaTests ===|
/home/sqeaky/Desktop/LuaTests/SourceDir/Lua/lua5.1/src/lapi.c||In function ‘index2adr’:|
/home/sqeaky/Desktop/LuaTests/SourceDir/Lua/lua5.1/src/lapi.c|67|error: ‘LUA_GLOBALSINDEX’ undeclared (first use in this function)|
/home/sqeaky/Desktop/LuaTests/SourceDir/Lua/lua5.1/src/lapi.c|67|note: each undeclared identifier is reported only once for each function it appears in|
/home/sqeaky/Desktop/LuaTests/SourceDir/Lua/lua5.1/src/lapi.c||In function ‘lua_replace’:|
/home/sqeaky/Desktop/LuaTests/SourceDir/Lua/lua5.1/src/lapi.c|213|error: ‘LUA_GLOBALSINDEX’ undeclared (first use in this function)|
||=== Build finished: 3 errors, 0 warnings ===|

Basically, there is some kind of internal global index that doesn’t exist in Lua 5.2, that does exist in 5.1. It seems the removal of anything global is probably a good move, particularly when you consider the increased cleanliness of the rest of the code in 5.2. Despite these improvements, I went with Lua 5.1, because it worked with SWIG.

After downgrading back to Lua 5.1 it still didn’t compile, here are the errors came from my code:

/home/sqeaky/Desktop/LuaTests/SourceDir/test.cpp||In function ‘int main(int, char**)’:|
/home/sqeaky/Desktop/LuaTests/SourceDir/test.cpp|9|error: ‘luaL_newstate’ was not declared in this scope|
||=== Build finished: 1 errors, 0 warnings ===|

Adding ‘#include “lauxlib.h”‘ fixes that missing declaration. I read a little bit of the Lua reference manual, specifically the index, and that made it more clear what is in the Lua Auxiliary library. Be careful when you are spelling that header file, it is The Lua Auxiliary Library, and not the Lua Xlib. I spelled it wrong and that prompted me to verify all the include directories in the project a few times, before I noticed the failed spelling.

With that extra header I started getting undefined references. For many programmers ‘Undefined References’ are rarely encountered pernicious errors that are fixed with unusual arcane solutions. Fixing them is one of the things every C++ developer should learn, but I have never it seen taught in classroom. Here are what the errors looked like when I made them:

CMakeFiles/LuaTests.dir/test.cpp.o||In function `main’:|
/home/sqeaky/Desktop/LuaTests/SourceDir/test.cpp|11|undefined reference to `luaL_newstate()’|
/home/sqeaky/Desktop/LuaTests/SourceDir/test.cpp|12|undefined reference to `lua_close(lua_State*)’|
||=== Build finished: 2 errors, 0 warnings ===|

What any undefined reference error means is that something has been declared, but the accompanying definition could not be found, even though something (the compiler, a command line arg, a config file, etc… ) said it should exist. If you are unclear on the meaning of Declarations vs Definitions, you should read up on this topic now. Many discussions and arcticles exist, they are a just a Google search away.

In this case I knew that the referred to code should be in the binary created by the custom Lua project I hacked together. I checked to see if it existed, and there indeed was a static library name liblua.a in my output directory. Since the binary existed, that means it must not be found correctly. There are a finite number of reasons that the required item would not be found. So I made a list of what I knew(not complete) about could cause this issue:

  1. The entire library might not be found.
  2. A different library with the same name might be found instead of the correct library.
  3. Name mangling issue. Finding the right part of the library.
  4. Some compilers require hints to declare what is in a library visible.

I started ruling out the issues one at a time. I deleted the library to see if the compiler would produce a different error. It did make a new error: ‘”-Llua” could not be found’ or something similar. This ruled out options 1 and 2, because I had isolated the exact file my compiler was trying to link against. Knowing that you are linking against the correct version of a library is important, if the headers you include are for an old version or you are suffering some other interesting mismatch you can get very subtle errors, which can take hundreds of programmer-hours to fix in real world scenarios. If you are lucky mismatched header and binary versions will produce a crash, I am never lucky so I check early if I suspect that a project might be using some system defined library rather than what I provided.

After that, I immediately ruled out Name Mangling. I do not have a very nuanced understanding of it, but I do understand that issues with it can arise if you mix binaries from different compiler versions or, misuse certain compiler options. I didn’t use any advanced compiler options, and both binaries were made by the same compiler, so this seemed impossible.

Finally, I ruled out needing to provide hints to the build tools about what was exposed in the resulting library. In general this isn’t required on Linux, in general it isn’t required with static libraries, and this isn’t at all needed with C (as opposed to C++). C provides a standardized ABI which makes available any items in the binary which are explicitly declared, by providing a header for example, in the calling code. I verified that Lua was indeed being compiled entirely as a C project, by checking the CMake documentation and the compiler logs, and cc was being called to compile Lua.

Out of real options, I decided to ask for help. I had John look at my code and he noticed that the file SWIG created was compiling fine, and it used plenty of items from Lua. With this newfound fact he left me to my devices again and I tried to tease out what this meant. The file ‘luabinding.cpp’ was 2,170 lines long and starts with the following warning:

/* —————————————————————————-
 * This file was automatically generated by SWIG (http://www.swig.org).
 * Version 2.0.1
 *
 * This file is not intended to be easily readable and contains a number of
 * coding conventions designed to improve portability and efficiency. Do not make
 * changes to this file unless you know what you are doing–modify the SWIG
 * interface file instead.
 * —————————————————————————– */

I verified the auto generated code compiling fine and was just being compiled later, by temporarily renaming lua.h. My next recompile produced dozens of errors instead of two. Many of these errors pointed to the internals of the file luabinding.h. This proved that file was compiling correctly, that means something in that file was could solve the undefined reference issues. I put the Lua files back how I found the, and I started testing the file by moving my main function to the end of it. It compiled fine.

What?! What can be placed in a file that can solve undefined references. So I started a binary search of luabinding.cpp by inserting, my main function in various places, to narrow down where this compiler magic was in the file was. It was above line 1000, below 500, above… After a few compiles I found exactly which line was fixing everything. I felt so stupid when I found it.

The magic was so ordinary and everyday, I just neglected a detail. The line was ‘extern “C” {‘ and the accompanying ‘}’. C guarantees a standard ABI for interconnecting various pieces of software and C++ leaves that up to the compiler. GCC was trying to use its C++ name mangling rules to find items in liblua.a that used the standard C ABI scheme. Deep down I knew it was doing this, but I never assembled the pieces mentally. Whenever you are calling C code or using variables declared in C from C++ they should be declared “extern” or have their declaration in an “extern” block. This was so simple, I can’t believe I wasted real time on this. Here is the compiling, but still incomplete test.cpp:

#include "test.h"

extern "C"
{
   #include "lua.h" // Lua Core
   #include "lauxlib.h" // Extra Lua Goodies like lua_open()
}

#include

int main (int argc, char** argv)
{
   std::cout << "This program will attempt to call a lua script that in turn runs a c function. This was output via cout streaming in c++ " << std::endl;
   lua_State *State; // create a pointer to Track the Lua State
   State = luaL_newstate(); // Create a Lua State
   lua_close(State); // Close the Lua state

   //once I get this simple test to compile I will try calling a lua script here
   //Once that script is being called I will try to call void PrintHello()

   return 0;
}

void PrintHello()
{
   std::cout << "Hello world! From PrintHello()" << std::endl;
}

Round 2 – The ‘almost’ Calling

Calling a Lua script should be pretty easy. I learned from the Lua documentation that the function luaL_dostring accepts a script as a c-string and returns an error code. It returns 0 on success and some other value on failure. So I added two more lines between creating and destroying the Lua state:

int Error = luaL_dostring(State,"print \"Hello from Lua\""); // run a very simple Lua script.
std::cout << std::endl << "Lua Error Code: " << Error << std::endl;

Here is the output with the Lua script included, sadly it did not contain the phrase “Hello from Lua” as I expected:

This program will attempt to call a lua script that in turn runs a c function. This was output via cout streaming in c++

Lua Error Code: 1

Process returned 0 (0×0) execution time : 0.004 s
Press ENTER to continue.

It is good to know that it didn’t crash, but I still needed to determine why it wasn’t running the script. To see if it was the Lua interpreter itself or some kind of failure with the print command, I tried changing the script to “– Lua Remark test”. This changed the output to include “Lua Error Code: 0″ and nothing else. Since two hyphens is a remark in Lua, nothing is exactly what I expected. This proved the interpreter it self wasn’t completely broken, however I still had a huge mystery on my hands.

I tried searching for a few examples of others calling Lua scripts from C++. I noticed that the Programming in Lua book (first reference to the function on lua.org that wasn’t inside the source) didn’t cover these details so clearly, but most people call luaopen_base or luaL_openlibs. The core Lua language only in has 21 keywords and 26 operators, and IO is completely left out. I had to learn from Stack Overflow that Chapter 5 of the Lua manual covers what is in each library.

/home/sqeaky/Desktop/LuaTests/SourceDir/test.cpp||In function ‘int main(int, char**)’:|
/home/sqeaky/Desktop/LuaTests/SourceDir/test.cpp|23|error: ‘luaL_openlibs’ was not declared in this scope|
||=== Build finished: 1 errors, 0 warnings ===|

So I must not have been including the correct files. When got here I had learned that all functions starting with “luaL_” were part of a Lua library rather than something in the Lua core language. I wondered if maybe some kind of preprocessor call was preventing the function I needed from being included. I investigated lauxlib.h and I did not see anything noteworthy. I did a grep of the source files and looked closely at the examples again. Any of the examples calling “Print” in Lua, and calling luaL_openlibs, also had ‘#include “lualib.h”‘ and this matched what I found while grepping. I added this and here was the result:

This program will attempt to call a lua script that in turn runs a c function. This was output via cout streaming in c++
Hello from Lua

Lua Error Code: 0

Process returned 0 (0×0) execution time : 0.006 s
Press ENTER to continue.

Inside of the code that SWIG created I found a function called luaopen_testscripting (after resolving macros). I added “extern int luaopen_testscripting(lua_State* L);” to the extern block at the top, I added a call to this function, and another running of a Lua script. Here is what the file look like at this point:

#include "test.h"

extern "C"
{
   #include "lua.h" // Lua Core
   #include "lualib.h" // for opening the base state
   #include "lauxlib.h" // Extra Lua Goodies like lua_open()

   extern int luaopen_testscripting(lua_State* L);
}

#include

int main (int argc, char** argv)
{
   std::cout << "This program will attempt to call a lua script that in turn runs a c function. This was output via cout streaming in C++." << std::endl;

   lua_State *State; // create a pointer to Track the Lua State
   State = luaL_newstate(); // Create a Lua State
   luaopen_base(State); // open the lua base library
   luaL_openlibs(State);
   luaopen_testscripting(State);

   int Error = luaL_dostring(State,"print \"Hello from Lua\""); // run a very simple Lua script.
   std::cout << std::endl << "Lua Error Code: " << Error << std::endl;

   Error = luaL_dostring(State,"PrintHello()"); // run a very simple Lua script.
   std::cout << std::endl << "Lua Error Code: " << Error << std::endl;

   lua_close(State); // Close the Lua state

   return 0;
}

void PrintHello()
{
   std::cout << "Hello world! From PrintHello()" << std::endl;
}

It compiles fine, but when running the second Lua Script:

This program will attempt to call a lua script that in turn runs a c function. This was output via cout streaming in C++.
Hello from Lua

Lua Error Code: 0

Lua Error Code: 1

Process returned 0 (0×0) execution time : 0.005 s
Press ENTER to continue.

I continued my experimentation with the code. I tried countless combinations of calling the Lua require function and several others. Printing in the same way the first scripting command works. At least running a script was not completely corrupting the Lua state. I could even fail to run one chunk, then successfully run another. I really needed more info about getting better error information from Lua. After I learned that if Lua is compiled as C++ it will use exceptions instead of longjmp I configured the cmake options to compile as C++ instead.

I added some more verbose error checking code, including the following function which checks Lua error codes.

int PrintErrorMessageOrNothing(int ErrorCode)
{
   switch(ErrorCode)
   {
      case 0: // Fine
         break;
      case LUA_YIELD: // most errors seem to be this.
         std::cout << std::endl << "Lua Error Code(LUA_YIELD): " << ErrorCode << std::endl;
         break;
      case LUA_ERRRUN:
         std::cout << std::endl << "Lua Error Code(LUA_ERRRUN): " << ErrorCode << std::endl;
         break;
      case LUA_ERRSYNTAX:
         std::cout << std::endl << "Lua Error Code(LUA_ERRSYNTAX): " << ErrorCode << std::endl;
         break;
      case LUA_ERRERR:
         std::cout << std::endl << "Lua Error Code(LUA_ERRERR): " << ErrorCode << std::endl;
         break;
      default:
         std::cout << std::endl << "Lua Error Code(Unknown Error): " << ErrorCode << std::endl;
   }
   return ErrorCode;
}

This function returned nothing but LUA_YIELD (even with obvious syntax errors) which I found wierd. Because I was nearing the end of my patience and couldn’t easily find information on this, I decided I would investigate further at another time.

I was near the end of my wits. I read the whole Lua manual and most of the SWIG documentation, specifically all of section 25 which covers Lua use in detail. So as a final measure of desperation I signed up for the SWIG mailing list. After a whole week I had received no reply. I decided to put this project down and work on some other items for a while.

Round 3 – The solution

So now… A few months have passed since I touched this project, and I have cleared my head. I reread the manual, and many things are more clear, but before I did that I ran some experiments then made a fool of myself on the SWIG mailing list.

I tried creating an separate interface file for SWIG to read instead of using the raw source. It looked like this:

%include stl.i
%module testscripting

void PrintHello();
int PrintErrorMessageOrNothing(int ErrorCode);

Which I put in luabinding.i and interpretted with the following command:

swig2.0 -c++ -v -lua -importall -o luabinding.h luabinding.i

It was so simple I was sure it would work, or work as well as anything I had tried so far. The SWIG part of it seemed to work. The version of luabinding.h it produced was even larger than before. It still compiled fine but failed when it ran, just like previous tests. After a few other tests I decided to seek help again.

I re-sent the exact same request for help to the SWIG mailing list. I contacted a few local programmers as well (Hats off to Nate for responding with an offer to help). I quickly got a reply showing how I misunderstood the Section 25.2.3 of the Manual. Since the mailing list responded first, I started a brief dialogue there and thanked everyone else.

After the discussion I learned what fine detail I was missing. I made the following change to my main function:

#include “test.h” // The declarations swig read

#include “lua.h” // Lua Core
#include “lualib.h” // for opening the base state
#include “lauxlib.h” // Extra Lua Goodies like lua_open()

#include “luabinding.h” // The File SWIG generated
#include

int main (int argc, char** argv)
{
   std::cout << "This program will attempt to call a lua script that in turn runs a c function. This was output via cout streaming in C++." << std::endl;

   lua_State *State; // create a pointer to Track the Lua State
   State = luaL_newstate(); // Create a Lua State
   luaL_openlibs(State);
   luaopen_testscripting(State);

   int Error = luaL_dostring(State,"print \"Hello from Lua\""); // run a very simple Lua script.
   PrintErrorMessageOrNothing(Error);

   Error = luaL_dostring(State,"testscripting.PrintHello()”); // works when planned out carefully
   PrintErrorMessageOrNothing(Error);

   lua_close(State); // Close the Lua state

   return 0;
}

After that simple change the output of the program became:

This program will attempt to call a lua script that in turn runs a c function. This was output via cout streaming in C++.
Hello from Lua
Hello world! From PrintHello()

Process returned 0 (0×0) execution time : 0.003 s
Press ENTER to continue.

Round 4 – Keeping it classy

No one likes a bad winner, so I need to keep it classy. Terrible puns aside, tight integration with classes is essential for a the C++, SWIG and Lua trifecta to be useful.

I tried to make a simple class that counts its amount of instantiations. Here are the parts I added to test.h:

class Countable
{
   private:
      static int TotalCount;
      int CreationCount;

   public:
      Countable();
      void PrintStatus();
};

int Countable::TotalCount = 0;

The implementation of the class was comparably simply. I added this to test.cpp:

// A simple constructor that causes this class to count the amount of instantiations
Countable::Countable()
{
   this->CreationCount=++Countable::TotalCount;
}

// What good is counting if we cannot see the results
void Countable::PrintStatus()
{
   std::cout << "This Countable is " << this->CreationCount << " of " << Countable::TotalCount << std::endl;
}

I had to add a little snippet to the main function to create the calling functionality in Lua. This is how I did that:

Error = luaL_dostring(State,”AnItem = testscripting.Countable() \
AnotherItem = testscripting.Countable() \
AnItem:PrintStatus() \
AnotherItem:PrintStatus() \
“); // works when planned out carefully
PrintErrorMessageOrNothing(Error);

Surprisingly all I had to do was re-run SWIG to regenerate luabinding.h then recompile, and it worked. Here is the Output during early test runs:

This program will attempt to call a lua script that in turn runs a c function. This was output via cout streaming in C++.
Hello from Lua
Hello world! From PrintHello()
This Countable is 1 of 2
This Countable is 2 of 2

Process returned 0 (0×0) execution time : 0.003 s
Press ENTER to continue.

This result seems completely successful. I will proceed with experiments and trying to better my understanding of SWIG boundary conditions. I will use this to keep experimenting for a while I begin work on integrating this into the game engine.

I have one more sample to output to share. This is after a little code clean up and small experiments. I also wanted to see Lua change values in C++ so I tried creating an instance of the Countable class after Lua altered it. Here we can see that if Lua changes the count it persists through to C++:

This program will attempt to call a Lua script that in turn runs a c function. This was output via cout streaming in C++.

Let’s try running a Lua command.
Hello from Lua

Now for a C++ function called from Lua.
Hello world! From PrintHello()

Now for some Lua class creation.
This Countable is 1 of 2
This Countable is 2 of 2

Let’s try one in C++.
This Countable is 3 of 3

Back to Lua for some more class creation.
This Countable is 4 of 5
This Countable is 5 of 5

Process returned 0 (0×0) execution time : 0.006 s
Press ENTER to continue.

In Summary

I have cleaned up the code, added many comments to explain why I did it. I removed the ‘extern’ commands in lieu of compiling Lua as C++. I consider this whole project a success, but a delayed one. I have learned a great deal about integrating scripting languages into projects and I hope this article help others. If you see a typo please let me know.

You can download complete version of this project as CppSWIGLua.tar.gz or as CppSWIGLua.zip.

If you want to duplicate my project without downloading the archives above you will need download the Lua Source and reconstruct the files from the following samples.

test.h:

// COPYRIGHT © 2012 Sqeaky
// This file can be used for any purpose, and can be considered public domain.

// This file will be read by SWIG to create luabinding.h
// This is also all the declaraions this simple program really needs.
// Header seem to be the ideal place for SWIG statements because it
// prevents the need to keep a separate file up to date constantly

// Gaurd to prevent multiple includes
#ifndef TEST_H
#define TEST_H

// only SWIG can read this
#ifdef SWIG
    %include stl.i
    %module testscripting
#endif

// A simple function for Lua to call.
void PrintHello();

// This accepts Lua error codes and return values and displays a message
// if there has been a problem.
int PrintErrorMessageOrNothing(int ErrorCode);

// A simple class that counts how many have been created.
class Countable
{
    private:
        static int TotalCount;
        int CreationCount;

    public:
        Countable();
        void PrintStatus();
};
int Countable::TotalCount = 0;

#endif

test.cpp:

// COPYRIGHT © 2012 Sqeaky
// This file can be used for any purpose, and can be considered public domain.

#include ”test.h”           // The declarations SWIG read

#include ”lua.h”            // Lua Core
#include ”lualib.h”         // for opening the base state
#include ”lauxlib.h”        // Extra Lua Goodies like lua_open()

#include ”luabinding.h”     // The File SWIG generated
#include 

int main (int argc, char** argv)
{
    std::cout << "This program will attempt to call a Lua script that in turn runs a c function. This was output via cout streaming in C++." << std::endl;

    lua_State *State;           // create a pointer to Track the Lua State
    State = luaL_newstate();    // Create a Lua State
    luaL_openlibs(State);
    luaopen_testscripting(State);

    std::cout << std::endl << "Let's try running a Lua command." << std::endl;
    int Error = luaL_dostring(State,"print \"Hello from Lua\"");    // run a very simple Lua script.
    PrintErrorMessageOrNothing(Error);

    std::cout << std::endl << "Now for a C++ function called from Lua." << std::endl;
    Error = luaL_dostring(State,"testscripting.PrintHello()");    // works when planned out carefully
    PrintErrorMessageOrNothing(Error);

    std::cout << std::endl << "Now for some Lua class creation." << std::endl;
    Error = luaL_dostring(State,"   AnItem = testscripting.Countable()          \
                                    AnotherItem = testscripting.Countable()     \
                                    AnItem:PrintStatus()                        \
                                    AnotherItem:PrintStatus()                   \
                                    ");
    PrintErrorMessageOrNothing(Error);

    std::cout << std::endl << "Let's try one in C++." << std::endl;
    Countable CppSample;
    CppSample.PrintStatus();

    std::cout << std::endl << "Back to Lua for some more class creation." << std::endl;
    Error = luaL_dostring(State,"   AnItem = testscripting.Countable()          \
                                    AnotherItem = testscripting.Countable()     \
                                    AnItem:PrintStatus()                        \
                                    AnotherItem:PrintStatus()                   \
                                    ");
    PrintErrorMessageOrNothing(Error);

    lua_close(State);           // Close the Lua state

    return 0;
}

int PrintErrorMessageOrNothing(int ErrorCode)
{
    switch(ErrorCode)
    {
        case 0:             // Fine
            break;
        case LUA_YIELD:     // most errors seem to be this.
            std::cout << std::endl << "Lua Error Code(LUA_YIELD): " << ErrorCode << std::endl;
            break;
        case LUA_ERRRUN:
            std::cout << std::endl << "Lua Error Code(LUA_ERRRUN): " << ErrorCode << std::endl;
            break;
        case LUA_ERRSYNTAX:
            std::cout << std::endl << "Lua Error Code(LUA_ERRSYNTAX): " << ErrorCode << std::endl;
            break;
        case LUA_ERRERR:
            std::cout << std::endl << "Lua Error Code(LUA_ERRERR): " << ErrorCode << std::endl;
            break;
        default:
            std::cout << std::endl << "Lua Error Code(Unknown Error): " << ErrorCode << std::endl;
    }
    return ErrorCode;
}

void PrintHello() // Function to call from Lua
{
    std::cout << "Hello world! From PrintHello()" << std::endl;
}

// A simple constructor that causes this class to count the amount of instantiations
Countable::Countable()
{
    this->CreationCount=++Countable::TotalCount;
}

// What good is counting if we cannot see the results
void Countable::PrintStatus()
{
    std::cout << "This Countable is " << this->CreationCount << " of " << Countable::TotalCount << std::endl;
}

CMakeLists.txt:

# Set up some some basic variables
cmake_minimum_required (VERSION 2.8)
project (LuaTests)

message (“${PROJECT_NAME} - Begin”)

# Can used to build this and Lua with any compiler flags. The flag for debug builds is included
set(CommonBuildFlags ${CMAKE_CXX_FLAGS_DEBUG})

add_definitions( ${CommonBuildFlags} )

# Some common variables I set up in many of my CMake Projects
set (${PROJECT_NAME}_ROOT_DIR ”${${PROJECT_NAME}_SOURCE_DIR}/”)
set (${PROJECT_NAME}_SOURCE_DIR ”${${PROJECT_NAME}_SOURCE_DIR}/”)
message ( STATUS ”Base Directory for ${PROJECT_NAME}: ${${PROJECT_NAME}_ROOT_DIR}”)

set (${PROJECT_NAME}_BINARY_DIR ”${${PROJECT_NAME}_BINARY_DIR}/bin/”)
set (PROJECT_BINARY_DIR ”${${PROJECT_NAME}_BINARY_DIR}”)
set (LIBRARY_OUTPUT_PATH ”${${PROJECT_NAME}_BINARY_DIR}”)
message ( STATUS ”Putting complete binaries in: ${${PROJECT_NAME}_BINARY_DIR}”)

# An array for the source files
set(${PROJECT_NAME}_sources
    ”test.cpp”
    ”test.h”
    ”luabinding.h”
)

#Tell compiler where to find lua binary and header
link_directories( ”${LuaTests_BINARY_DIR}/libs/” )
include_directories(
    ”${${PROJECT_NAME}_SOURCE_DIR}/Lua/lua-5.2.0/src/”
    ”${${PROJECT_NAME}_SOURCE_DIR}/Lua/lua5.1/src/”
)

# Include the Lua project
add_subdirectory (Lua)

# Define the output executable and what it relies on and must link against.
add_executable(${PROJECT_NAME} ${${PROJECT_NAME}_sources})
add_dependencies( ${PROJECT_NAME} Lua )
target_link_libraries( ${PROJECT_NAME} lua)

message ( STATUS ”Putting lua binaries in: ${LIBRARY_OUTPUT_PATH}”)

message (“${PROJECT_NAME} - End”)

Lua/CMakeLists.txt:

cmake_minimum_required (VERSION 2.8)
project (Lua)

add_definitions( ${CommonBuildFlags} )

message (“${PROJECT_NAME} - Begin”)

# All the source files
set(${PROJECT_NAME}_sources
    ”lua5.1/src/lapi.h”
    ”lua5.1/src/lauxlib.h”
    ”lua5.1/src/lcode.h”
    ”lua5.1/src/ldebug.h”
    ”lua5.1/src/ldo.h”
    ”lua5.1/src/lfunc.h”
    ”lua5.1/src/lgc.h”
    ”lua5.1/src/llex.h”
    ”lua5.1/src/llimits.h”
    ”lua5.1/src/lmem.h”
    ”lua5.1/src/lobject.h”
    ”lua5.1/src/lopcodes.h”
    ”lua5.1/src/lparser.h”
    ”lua5.1/src/lstate.h”
    ”lua5.1/src/lstring.h”
    ”lua5.1/src/ltable.h”
    ”lua5.1/src/ltm.h”
    ”lua5.1/src/luaconf.h”
    ”lua5.1/src/lua.h”
    ”lua5.1/src/lualib.h”
    ”lua5.1/src/lundump.h”
    ”lua5.1/src/lvm.h”
    ”lua5.1/src/lzio.h”

    ”lua5.1/src/lapi.c”
    ”lua5.1/src/lauxlib.c”
    ”lua5.1/src/lbaselib.c”
    ”lua5.1/src/lcode.c”
    ”lua5.1/src/ldblib.c”
    ”lua5.1/src/ldebug.c”
    ”lua5.1/src/ldo.c”
    ”lua5.1/src/ldump.c”
    ”lua5.1/src/lfunc.c”
    ”lua5.1/src/lgc.c”
    ”lua5.1/src/linit.c”
    ”lua5.1/src/liolib.c”
    ”lua5.1/src/llex.c”
    ”lua5.1/src/lmathlib.c”
    ”lua5.1/src/lmem.c”
    ”lua5.1/src/loadlib.c”
    ”lua5.1/src/lobject.c”
    ”lua5.1/src/lopcodes.c”
    ”lua5.1/src/loslib.c”
    ”lua5.1/src/lparser.c”
    ”lua5.1/src/lstate.c”
    ”lua5.1/src/lstring.c”
    ”lua5.1/src/lstrlib.c”
    ”lua5.1/src/ltable.c”
    ”lua5.1/src/ltablib.c”
    ”lua5.1/src/ltm.c”
    ”lua5.1/src/lua.c”
    ”lua5.1/src/luac.c”
    ”lua5.1/src/lundump.c”
    ”lua5.1/src/lvm.c”
    ”lua5.1/src/lzio.c”
    ”lua5.1/src/print.c”
    # ”lua5.1/src/wmain.c”
)

# Force C++
set_source_files_properties( ${${PROJECT_NAME}_sources} PROPERTIES LANGUAGE ”CXX” )

# Where the resulting cpp project should search for headers
include_directories(
    ”${${PROJECT_NAME}_SOURCE_DIR}/lua5.1/src/”
)

# Where to dump the results
set (LIBRARY_OUTPUT_PATH ”${LuaTests_BINARY_DIR}/libs/”)

message ( STATUS ”Putting lua binaries in: ${LIBRARY_OUTPUT_PATH}”)

# Make a binary with the given source files0
add_library(lua STATIC ${${PROJECT_NAME}_sources})
message (“${PROJECT_NAME} - End”)

Share

Chrome OS is Getting Talked About

If you haven’t heard yet Google is announcing a new Operating System centered around their Chrome Web browser. They officially announced it July 7th. Some are unsure what to think, while others are concerned. Some know it will succeed, while others know it will fail. What does this mean for android Google’s other operating system? This new development from Google is certainly causing a huge buzz regardless of what it means for everyone else.
 
One thing I am certain of is that it won’t fail for lack of Publicity. If you were paying attention to the here and now, you noticed that every word in this article is a link. Other than technical terms every link is to a different news story about Chrome OS. Few can generate press as well as Google. Since this news broke it has felt like the Internet was Google’s personal broken record player. HINT: It stops being news when everyone knows about it.
 
Google has proclaimed that it won’t be available for a long time. It is vaporware just like Duke Nuke’m 4ever. It is only real and only actually matters once it is on our computers. Yes, I welcome this, but I wish everyone would take a hearty dose of perspective.

Share

Battle for Wesnoth

Me and and my buddy Steve started playing Battle for Wesnoth, and this is like the most addicting strategy game I have ever played. It is almost as addicting as Tetris. It is turn based strategy game, based in the medieval/fantasy world of Wesnoth. There is actual thought and strategy required, so I recommend that you go through the one player campaign the “Sceptre of Fire” Tutorial which shows you the basics first.
 
Unlike most games there are multiple one player campaigns. So once you beat the game, there is still more to do. I highly suggest you play a few campaigns before you jump into the multi-player. Some of the online players are really cut-throat. If online isn’t your thing, you can always design your own campaign with the built in campaign and map editors.
 
In Ubuntu just install the wesnoth-all package, I used “sudo apt-get install wesnoth-all”, you can use Add/Remove programs if you want to use you mouse. In windows I have no clue if the extra campaigns come with it or where to get them (I assume they are included). If anyone knows, please let me know. Either way, I am off to waste my Saturday on this game. :)
 
EDIT: I was looking so hard for the add-ons on the website that I never looked in the game. Take a look at the main menu and look at the add-ons button. There is tons of stuff in here I remember the sceptre of fire campaign as being easy, because I use to play this game a long time ago, and beat that campaign handily. The campaign to play would be heir to the throne, it is tightly integrated with the tutorial if I remember clearly.

Share