Lua stack dump for c++

Any interactions between c++ and lua are going through lua stack. Aware of the stack status may help for debugging. I always do that, will a peek of the current Lua stack not only helps me debug my codes but also helps me figure out the ways how I can pass table from c++ to Lua and vice versa.

void stackdump_g(lua_State* l)
{
    int i;
    int top = lua_gettop(l);

    printf("total in stack %d\n",top);

    for (i = 1; i <= top; i++)
    {  /* repeat for each level */
        int t = lua_type(l, i);
        switch (t) {
            case LUA_TSTRING:  /* strings */
                printf("string: '%s'\n", lua_tostring(l, i));
                break;
            case LUA_TBOOLEAN:  /* booleans */
                printf("boolean %s\n",lua_toboolean(l, i) ? "true" : "false");
                break;
            case LUA_TNUMBER:  /* numbers */
                printf("number: %g\n", lua_tonumber(l, i));
                break;
            default:  /* other values */
                printf("%s\n", lua_typename(l, t));
                break;
        }
        printf("  ");  /* put a separator */
    }
    printf("\n");  /* end the listing */
}

I usually interested on knowing how many blocks in my stack had been occupied and also each block’s variable type, if they are string, number or bool, I would like to know the value as well.

The usage is simple, you will only needs to pass in your current Lua State pointer.

The print line output may look like this:


total in stack 2
string: '5A5B5C8855778899'
  number: 89

Static Linking Compilation for Boost C++ Libraries

Boost C++ Libraries provides a set of peer-reviewed portable C++ source libraries. As we know, coding in c++, there are a lots of things we need to write it from scratch, we need to create a common socket class, threading class, logging class, regex functions etc. Developing those libraries sometimes takes too much time, and that makes most of the programmers suffer while given a very tide time line and consequently the companies and its customers will suffer. At this point, the codes will reach End of Life, a new groups of developers comes in, reinvent the codes which may equally sucks and this infinite loops goes on.

Boost provides a set of libraries which will really saves a lots of development cost. But use boost libraries with some cares. There are few things to bare in mind while embedding boost libraries into your codes.

1. Some Boost libraries needs additional dynamic linking by defaults.
2. Different version of Boost dynamic libraries do not compatible.
3. Different version of glibc may have different set of dynamic libs for the same boost version.

For statement 1, there are libraries such as Boost.Thread and Boost.Regex uses dynamic linking by default. Fortunately boost have static linking for those boost libs too.

For statement 2, the application that needs dynamic linking compiled with Boost version A, does not able to run with dynamic lib of Boost version B. Damn! That the reason I prefer static linking.

For statement 3, In Linux environment, codes that compile with gcc 4.1 may not run in Linux with gcc 3.4 because they uses different glibc runtime libraries. But what if you are using latest workstation such as Fedora 9 and aim to compile codes to work in Red Hat ES4? You may have few set of gcc with different version. For my case, my default GCC is 4.1, but I have GCC 3.4 installed too. During compilation, I need to use gcc34 or g++34 instead. While compiling the Boost libraries, you need to specified the gcc version, so that the static and dynamic libs may based on the correct version of glibc.

Compile Boost Library support static linking, with specified gcc versions

1. Download Boost, my case, boost_1_35_0.tar.bz2.

2. ./configure
(by default libs and header files will install in /usr/local, while running ./configure, you can specified your target location with –prefix) i.e ./configure –prefix=/usr

3. Edit user-config if you are wants the to compile Boost with specific GCC version.
My case I modify the line
using gcc ;
To
using gcc : 3.4 : g++34 ;

4. If you want static linking lib for boost, you need to do full compilation. Modify Makefile after running ./configure
BJAM_CONFIG=–build-type=complete

5, make; sudo make install

Boost lib will be installed to :
/usr/local/lib/libboost_*
Boost includes will be located at:
/usr/local/include/boost-1_35

Compile codes using Boost.Thread Static library
This is a simple example on how you compile your codes what uses Boost.Thread static lib.

g++34 -o myApp{,.cc} -I/usr/local/include/boost-1_35/ -L/usr/local/lib -lboost_thread-gcc34-mt-s -lpthread

(Bare in mind if you are using static linking, you need to specified -lpthread, if you are using dynamic linking, you may ignore -lpthread.)

Enjoy hacking with boost!

Calling Lua function from C++

Calling Lua function from c++ is very simple. Value passing between c++ and Lua goes through stack, Lua C API provides a convenience ways for you to call Lua function from C. To call Lua function, you need to specify:

1. Function Name.
2. Parameters of function call.
3. Return values expected ( Lua function support multiple results reture)

Let say my lua function name call f in last.lua, takes 2 parameters.

-- last.lua
function f (x, y)
    return (x^2 * math.sin(y))/(1 - x)
end

I perform function call from c++ like this:

//last.cc
# extern "C" {
# #include "lua.h"
# #include "lualib.h"
# #include "lauxlib.h"
# }  

int main()
{
    double z;
    lua_State *L = lua_open();
    luaL_openlibs(L);
    if (luaL_loadfile(L, "last.lua") || lua_pcall(L, 0, 0, 0)) {
        printf("error: %s", lua_tostring(L, -1));
        return -1;
    }

    lua_getglobal(L, "f");
    if(!lua_isfunction(L,-1))
    {
        lua_pop(L,1);
        return -1;
    }
    lua_pushnumber(L, 21);   /* push 1st argument */
    lua_pushnumber(L, 31);   /* push 2nd argument */

    /* do the call (2 arguments, 1 result) */
    if (lua_pcall(L, 2, 1, 0) != 0) {
        printf("error running function `f': %s\n",lua_tostring(L, -1));
        return -1;
    }

    /* retrieve result */
    if (!lua_isnumber(L, -1)) {
        printf("function `f' must return a number\n");
        return -1;
    }
    z = lua_tonumber(L, -1);
    printf("Result: %f\n",z);
    lua_pop(L, 1);
    lua_close(L);

    return 0;
}

Compile it with g++ like this:

g++ -o last{,.cc} -llua -ldl

The results:

Result: -12.158958

Brief explanation of the C++ codes above:
First, I trigger lua_getglobal to get the function name, then I push 2 parameters to stack. I make lua_pcall by telling Lua I have 2 params and expect 1 value return. Upon success, I retrieve the return value from the top of the stack.