使用lua c API从表中提取userdata

时间:2015-02-15 05:45:16

标签: c++ c lua lua-table lua-api

我使用lua c api来循环表中的变量,比如

lua脚本:

array = {0,1,2,3}

lua c api

lua_getglobal(l, "array");
if(lua_isnil(l, -1)) {

}
lua_pushnil(l);
while(lua_next(l, -2)) {

    int value=(int)lua_tonumber(l, -1);
    printf("%d \n",value);

    lua_pop(l, 1);
}

我可以得到结果

0 1 2 3

然后我想把一些userdata objs放到表中 然后在c api中循环它们

lua脚本

foo0 = Foo.new("fred0")
foo1 = Foo.new("fred0")
foo2 = Foo.new("fred0")
foo3 = Foo.new("fred0")
array = {foo0,foo1,foo2,foo3}

lua c api

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

#include <iostream>
#include <sstream>

#include <vector>

class Foo
{
public:
    Foo(const std::string & name) : name(name)
    {
        std::cout << "Foo is born" << std::endl;
    }

    std::string Add(int a, int b)
    {
        std::stringstream ss;
        ss << name << ": " << a << " + " << b << " = " << (a+b);
        return ss.str();
    }

    ~Foo()
    {
        std::cout << "Foo is gone" << std::endl;
    }

    std::string name;
};


int l_Foo_constructor(lua_State * l)
{
    const char * name = luaL_checkstring(l, 1);

    Foo ** udata = (Foo **)lua_newuserdata(l, sizeof(Foo *));
    *udata = new Foo(name);

    luaL_getmetatable(l, "luaL_Foo");

    lua_setmetatable(l, -2);

    return 1;
}




Foo * l_CheckFoo(lua_State * l, int n)
{
    return *(Foo **)luaL_checkudata(l, n, "luaL_Foo");
}

int l_Foo_add(lua_State * l)
{

    return 1;
}

int l_Foo_destructor(lua_State * l)
{
    Foo * foo = l_CheckFoo(l, 1);
    delete foo;

    return 0;
}

void RegisterFoo(lua_State * l)
{
    luaL_Reg sFooRegs[] =
    {
        { "new", l_Foo_constructor },
        { "add", l_Foo_add },
        { "__gc", l_Foo_destructor },
        { NULL, NULL }
    };

    luaL_newmetatable(l, "luaL_Foo");

    luaL_register(l, NULL, sFooRegs);

    lua_pushvalue(l, -1);

    lua_setfield(l, -1, "__index");

    lua_setglobal(l, "Foo");
}

int main()
{
    lua_State * l = luaL_newstate();
    luaL_openlibs(l);
    RegisterFoo(l);

    int erred = luaL_dofile(l,"/Volumes/Work/CODE/Test/testStatic/testStatic/kami.txt");
    if(erred)
        std::cout << "Lua error: " << luaL_checkstring(l, -1) << std::endl;



    lua_getglobal(l, "array");
    if(lua_isnil(l, -1)) {
        //return std::vector();
    }
    lua_pushnil(l);

    std::vector<Foo *> v;
    while(lua_next(l, -2)) {


        Foo * foo = l_CheckFoo(l, -1);//this line do not work
        //
        //
        //
        //
        //I don't know how to do it here.
        //
        //
        //
        //
        //v.push_back(foo);
        lua_pop(l, 1);
    }


//    for (Foo* theValue:v)
//    {
//        printf("==>%s",theValue->name.c_str());
//    }

    lua_close(l);

    return 0;
}

如何从表中提取userdata? 请帮帮我,谢谢。

1 个答案:

答案 0 :(得分:0)

最后我自己把它吹过来

l_CheckFoo(l, -1);

应该是

lua_touserdata(l, -1);

void * hehe=lua_touserdata(l, -1);

Foo ** haha=(Foo **)hehe;

Foo *f=*haha;

printf("%s \n",f->name.c_str());