Lua C ++ userdata

时间:2015-06-21 03:24:06

标签: c++ lua

我正在尝试访问userdata的类型,以便我可以相应地处理它。想象一下,我有一个名为Foo的类:

class Foo:public CObject
{
 public:
 Foo():CObject(){}
 int type() {return 1;}
}

class CObject
{
 public:
 virtual int type(void)=0;
}

基本原理是每个扩展CObject的类都有一个必须用整数表示的类型(稍后在枚举上)。 Foo类使用luaWwrapper(// https://bitbucket.org/alexames/luawrapper/src/fd9c4fdbf4b25034e3b8475a2c8da66b7caab427?at=default)绑定到lua。

  Foo* Foo_new(lua_State* L)
  {
    Foo* f=new Foo();
    lua_newuserdata(L,sizeof(f));
    std::cout<<"f="<<f;
    return f;
  }

在Lua中,用户将其称为:

f=Foo.new() 
print(f)

现在我有一个C ++函数,比如print:

int lua_print(lua_State* L)
{
   void *ud = luaL_checkudata(L, 1, "Foo"); //ud is not zero
    std::cout<<"ud="<<ud;
    CObject* obj=(CObject*)ud;  //Casting to CObject
   int objtype=obj->type();   //program CRASHES here

}

我看到程序崩溃导致Fooud的内存地址不一样。我假设 ud指的是包含Foo内存地址的堆栈内存。如何访问堆栈的内存地址或Foo的首选内存地址?

2 个答案:

答案 0 :(得分:1)

您必须使用placement new来初始化lua_newuserdata 返回的内存中的对象

中的某些内容
void *ud = lua_newuserdata(L,sizeof(Foo));
new (ud) Foo();

答案 1 :(得分:0)

Foo_new应该只返回指向对象的指针。

换句话说,你的Foo_new看起来像这样:

Foo* Foo_new(lua_State* L)
{
  return new Foo();
}

但是,如果您没有需要进行特殊初始化,则甚至不需要编写此函数。如果您不自己编写,可以使用魔法模板为您提供此功能。

如果要从Lua状态获取Foo对象,请执行以下操作:

int lua_print(lua_State* L)
{
   Foo *ud = luaW_to<Foo>(L, 1); //ud is not zero
   std::cout<<"ud="<<ud;
   CObject* obj=(CObject*)ud;
   int objtype=obj->type();
}

如果CObject也注册了LuaWrapper,您甚至不需要进行手动播放。你可以luaW_to<CObject>(L, 1);