lua userdata

#define metatablename "studentlib.06-11-11"
/**
 * utility functions
 */

static int pusherror(lua_State *L, const char *info = NULL)
{
    lua_pushnil(L);
    if(info)
    {
        lua_pushfstring(L, "%s :%s", info, strerror(errno));
    }
    else
    {
        lua_pushstring(L, strerror(errno));
    }
    lua_pushinteger(L, errno);
    return 3;
}


/**
 * the struct in c
 */
struct studentTag
{
    char *name;
    int no;
    int   sex;
    int   age;
};
static int student_gc(lua_State *L)
{
    studentTag *pStudent = (studentTag *)lua_touserdata(L, 1);
    if(pStudent->name)
    {
        free(pStudent->name);
        //printf("student_gc()\n");
    }

    return 0;
}
static int newStudent(lua_State *L)
{
    size_t nBytes = sizeof(studentTag);
    studentTag *pStudent =  (studentTag *)lua_newuserdata(L, nBytes);
    luaL_setmetatable(L, metatablename);
    return 1;
}

static int setName(lua_State *L)
{
    studentTag *pStudent = (studentTag *)luaL_checkudata(L, 1, metatablename);
    const char *name = luaL_checkstring(L, 2);
    luaL_argcheck(L, name != NULL && name != "", 2, "expect a name");
    pStudent->name = (char *)malloc(luaL_len(L, 2) + 1);
    if(pStudent->name == NULL)
    {
        pusherror(L);
    }
    strcpy(pStudent->name, name);
    return 0;
}
static int getName(lua_State *L)
{
    studentTag *pStudent = (studentTag *)luaL_checkudata(L, 1, metatablename);
    lua_pushstring(L, pStudent->name);
    return 1;
}
static int setNo(lua_State *L)
{
    studentTag *pStudent = (studentTag *)luaL_checkudata(L, 1, metatablename);
    int no = luaL_checkinteger(L, 2);
    luaL_argcheck(L, no > 0, 2, "invalid number");
    pStudent->no = no;
    return 0;
}
static int getNo(lua_State *L)
{
    studentTag *pStudent = (studentTag *)luaL_checkudata(L, 1, metatablename);
    lua_pushinteger(L, pStudent->no);
    return 1;
}
struct luaL_Reg lib_m[] =
{
    {"setName", setName},
    {"name", getName},
    {"setNo", setNo},
    {"no", getNo},
    {NULL, NULL}
};
struct luaL_Reg lib_f[] =
{
    {"new", newStudent},
    {NULL, NULL}
};
extern "C" __declspec(dllexport) int luaopen_student(lua_State *L)
{
    luaL_newmetatable(L, metatablename);
    lua_pushvalue(L, -1);
    lua_setfield(L, -2, "__index");
    lua_pushcfunction(L, student_gc); //
    lua_setfield(L, -2, "__gc");
    luaL_setfuncs(L, lib_m, 0);

    lua_newtable(L); // 相当于 newlib
    luaL_setfuncs(L, lib_f, 0);

    lua_pushliteral(L, "Copyright (C) 2016-2018 Kepler Project");
    lua_setfield(L, -2, "_COPYRIGHT");
    lua_pushliteral(L, "a lua library for a student struct");
    lua_setfield(L, -2, "_DESCRIPTION");
    lua_pushliteral(L, "1.0");
    lua_setfield(L, -2, "_VERSION");
    return 1;
}

posted on 2016-11-22 13:01  ShawSpring  阅读(140)  评论(0)    收藏  举报

导航