2015-06-21 123 views
1

我试图访问一个userdata的类型,以便我可以相应地处理它。想象我有一个命名为Foo类:Lua C++ userdata

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

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

的理由是,延伸的CObject的每一个类具有必须由通过的整数已知的类型(以后枚举)。 Foo类使用luaWwrapper绑定到lua(// https://bitbucket.org/alexames/luawrapper/src/fd9c4fdbf4b25034e3b8475a2c8da66b7caab427?at=default)。

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++函数,比如说打印:

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的内存地址不一样。 I 假定ud是指包含Foo的存储器地址的堆栈的存储器。如何访问堆栈的内存地址或Foo的首选内存地址?

回答

1

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

在东西线的

void *ud = lua_newuserdata(L,sizeof(Foo)); 
new (ud) Foo(); 
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);