我正在尝试访问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
}
我看到程序崩溃导致Foo
和ud
的内存地址不一样。我假设 ud
指的是包含Foo
内存地址的堆栈内存。如何访问堆栈的内存地址或Foo
的首选内存地址?
答案 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);