lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> BTW, I think LUA is great, I just wish I can get this to work. Thanks.
> 
> My app dumps core somewhere within the stl code. Here is the backtrace:
> #0  GameMap::AddTileBitmap (this=0x0, image=0x805f608)
>     at /usr/local/include/g++/stl_vector.h:145
> 145         if (finish != end_of_storage) {
> (gdb) bt
> #0  GameMap::AddTileBitmap (this=0x0, image=0x805f608)
>     at /usr/local/include/g++/stl_vector.h:145

Here's your clue:
> #1  0x8049b83 in GameMap::AddTile (this=0x0) at game_map.cpp:56
                                    ^^^^^^^^^^
You cast the member function GameMap::AddTile to function you registered
with lua.  lua has no way to know it's a "thiscall" (i.e.: attached to
an object) so it just calls it like a standard C function (which it isn't).

What I generally do, is make my tables have a "ptr" member, which I 
set to point to the C++ object I'm working with.  Then in the LUA->C
binding function, I fetch that member from the table passed to the C
function and dereference it to call the object member function.

lua_Object getField(lua_Object t, char *fld)
{
    lua_pushobject(t);
    lua_pushstring(fld);
    return lua_gettable();
}

// push a userdata (void*) object..
void setField(lua_Object t, char *fld, void *data, int tag = 0)
{
    lua_pushobject(t);
    lua_pushstring(fld);
    lua_pushusertag(data,type);
    lus_settable();
}

// push a cfunction object..
void setField(lua_Object t, char *fld, void (*data)())
{
    lua_pushobject(t);
    lua_pushstring(fld);
    lua_pushcfunction(data);
    lus_settable();
}

// functions to bind to LUA; make sure they are C callable.
// (in general, a C++ function with no args has the same linkage as a
// C function, but that's implementation dependent, so avoid link-time
// errors, by declaring the function as a C function).
extern "C" { 
    static void lua_myClass_AddTile();
}


// class which is usable from lua.  each member function that is to be
// called, should be added as a field ; we might want to create a tag,
// etc.  We could also make a "luaObject" baseclass which would do 
// all of the common objects-accessable-to-lua initialization.  
class myClass {
    void AddTile();

    lua_Object t;
    int ref;

    // constructor ..
    myClass() {
	t = lua_createTable();	// create new lua object
	ref = lua_ref(1);	// lock it in memory.

	// add member function
	setField(t,"AddTile", lua_myClass_AddTile);

	// add pointer to 'this' for lua linkage
	setField(t,"ptr", (void*)this);
    }

    ~myClass() {
	if (ref) lua_unref(ref);
	// ... etc ..
    }
}

// it's a pity that cfunction's in lua don't get to carry userdat, then we
// could pass the object "implicitly" to the C -> C++ binding function.
// instead of digging it out of a table.
static void lua_myClass_AddTile() {
    lua_Object table = luaL_tablearg(1);	// get table from lua
    MyClass *self = (MyClass*) lua_getuserdata( getField(t,"ptr"));

    self->addTile();
}


--
Mike Cuddy (mcuddy@FensEnde.com, MC312), Programmer, Daddy, Human.
Fen's Ende Software, Redwood City, CA, USA, Earth, Sol System, Milky Way.
I remember asking why ... Let it rain, and protect us from this Cruel Sun.

       Join CAUCE: The Coalition Against Unsolicited Commercial E-mail.  
                          <http://www.cauce.org/>