Sign in to follow this  

beginner's question: writing a module in C

This topic is 3294 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hi, since some hours now i'm fighting with my first lua program. i have written a C file which creates a module based on a userdata pointer and assigns a metatable with a garbage collector. i have two problems: executing the following script crashes the VM because i'm freeing an invalid value: p=page.alloc() page.free(p) the other problem is that the garbage collector is never called: p=page.alloc() p=nil -- doesn't call the garbage collector here's the module:
static int
__stub_page_alloc(lua_State *L)
{
    char *ptr=(char *)lua_newuserdata(L, 1024*4);
    return 1;
}

static int
__stub_page_free(lua_State *L)
{
    char *ptr=(char *)lua_touserdata(L, 1);
    free(ptr);
    return 1;
}

static const luaL_reg page_methods[] = {
    { "alloc", __stub_page_alloc},
    { "free",  __stub_page_free},
    { 0,       0}
};

static int
__stub_page_gc(lua_State *L)
{
    printf("gc!\n");
    __stub_page_free(L);
    return 0;
}

static const luaL_reg page_meta[] = {
    { "__gc",  __stub_page_gc},
    { 0,       0}
};

int main(void)
{
    lua_State *L=lua_open();
    luaopen_base(L);

    luaL_openlib(L, "page", page_methods, 0);
    luaL_newmetatable(L, "page");
    luaL_openlib(L, 0, page_meta, 0);
    lua_pushliteral(L, "__index");
    lua_pushvalue(L, -3);
    lua_rawset(L, -3);
    lua_pushliteral(L, "__metatable");
    lua_pushvalue(L, -3);
    lua_rawset(L, -3);
    lua_pop(L, 1);

    if (luaL_dofile(L, NULL)!=0)
        fprintf(stderr, "%s\n", lua_tostring(L, -1));
    lua_close(L);
    return 0;
}
the code is copied from /etc/min.c in the lua tarball and from http://lua-users.org/wiki/UserDataWithPointerExample. thanks in advance Chris

Share this post


Link to post
Share on other sites
Maybe you are following an old tutorial? I looked at the code a bit and found some things that may be wrong.

__stub_page_free() returns 1 but it should be 0. It may result in the deleted userdata to be returned again.

luaL_openlib(L, 0, page_meta, 0) passes an empty string as the table name. This probably results in nil being pushed onto the stack so the following lua_rawset() calls tries to assign values to nil. luaL_openlib() is not in the documentation for the current version of Lua.

To set the metatable lua_setmetatable() should be used. "__metatable" is perhaps how it was done before version 5.

I sometimes write the contents of the stack to the right of the functions when trying to follow Lua code. No guarantee that the code below is correct :-)

luaL_openlib(L, "page", page_methods, 0);	// table "page"
luaL_newmetatable(L, "page"); // table "page", table "page"
luaL_openlib(L, 0, page_meta, 0); // table "page", table "page", nil?
lua_pushliteral(L, "__index"); // table "page", table "page", nil?, "__index"
lua_pushvalue(L, -3); // table "page", table "page", nil?, "__index", table "page"
lua_rawset(L, -3); // table "page", table "page", nil?
lua_pushliteral(L, "__metatable"); // table "page", table "page", nil? "__metatable"
lua_pushvalue(L, -3); // table "page", table "page", nil? "__metatable", table "page"
lua_rawset(L, -3); // table "page", table "page", nil?
lua_pop(L, 1); // table "page", table "page"


Try to make the stack go back to 0 depth after doing a certain task. It seems like there are still two tables pushed onto it. You could write a simple C++ class that checks that lua_gettop() has the same value at the beginning and end of a function for example.

Share this post


Link to post
Share on other sites

This topic is 3294 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this