Joshua Waring
Joshua Waring

Reputation: 619

Lua doesn't return my userdata

I've been having some unexpected issues with my touserdata and newuserdata, the data passed to C++ is not the same that is stored when I create the userdata, below I have all the functions related to the creation and the functions that I'm calling (

I create my avatar with this lua code avatar = avatar_create("hero1") which in c++ is this

int LuaObjectFactory::createAvatar(lua_State* L){ 
    auto avatar = new Avatar(lua_tostring(L, 1)); // 0x011afd20
    auto userdata = Util::luaP_newuserdata<Avatar>(L, avatar); // 0x011a4a18
    luaP_getScenes(L)->getActiveScene()->addEntity(avatar); 
    Util::luaP_setmetatable(L, Avatar::lGetMetatable());
    return 1;
}
template<typename T> T** luaP_newuserdata(lua_State* L, T* data){
    T** o = static_cast<T**>(lua_newuserdata(L, sizeof(T*)));
    // Does not copy the data, only remembers reference to it
    *o = data;
    return o;
}

inline void luaP_setmetatable(lua_State* L, const string& metatable){
    luaL_getmetatable(L, &metatable[0]);
    lua_setmetatable(L, -2);
}

template<typename T> T* luaP_touserdata(lua_State* L, int idx){
    return *static_cast<T**>(lua_touserdata(L, idx));
}   

then later on I try to call a function of Avatar's with this lua code

avatar = avatar_create("hero1") 
avatar:setPosition(12, 10)
avatarPos = avatar:getPosition() 

which calls these two functions

template<typename T> static int lGetPosition(lua_State* L){
    auto p = Util::luaP_touserdata<T>(L, 1); // 0x008ff0d8
    auto v = p->getPosition();
    lua_pushnumber(L, v.x);
    lua_pushnumber(L, v.y);
    return 0;
}

template<typename T> static int lSetPosition(lua_State* L){
    auto p = Util::luaP_touserdata<T>(L, 1); // 0x008ff0d8
    auto v = Math::Vector2(static_cast<int>(lua_tonumber(L, 2)),
        static_cast<int>(lua_tonumber(L, 3)));
    p->setPosition(v);
    return 0;
}

I commented the memory addresses returned from on of my attempts of debugging, the luaP_touserdata returns the same address, although even so the values that I set on 0x008ff0d8 have been erased when I go to get them later

Something else I noticed is that the address of 0x008ff0d8 is a pointer to a pointer which points back to 0x008ff0d8.

Upvotes: 2

Views: 341

Answers (1)

Dmitry Ledentsov
Dmitry Ledentsov

Reputation: 3660

Why aren't you using a dedicated binding layer, such as luabridge or luabind? The low level problems you're struggling with in spaghetti code are effectively solved in many binding libraries.

There are even some that use modern c++, such as Selene and LuaGlue or luawrapper and luapp11

Upvotes: 1

Related Questions