Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lua_touserdata is returning null

I am badly stuck trying to get my userInfo reference. One of my method is returning instance of the object. Everytime createUserInfo is called, it will return the userInfoObject to the lua.

However, when I call a method for userInfo object from Lua, I am not able to get the reference of the userInfo object (lua_touserdata(L,1))

static int getUserName (lua_State *L){
   UserInfo **userInfo = (UserInfo**)lua_touserdata(L,1);

   // The following is throwing null! Need help. 
   // Not able to access the userInfo object.
   NSLog(@"UserInfo Object: %@", *userInfo);       
}

static const luaL_reg userInstance_methods[] = {
  {"getUserName", getUserName},
  {NULL, NULL}
}

int createUserInfo(lua_State *L){

  UserInfo *userInfo = [[UserInfo alloc] init];
  UserInfoData **userInfoData = (UserInfoData **)lua_newuserdata(L, sizeof(userInfo*));
  *userInfoData = userInfo;

  luaL_openlib(L, "userInstance", userInstance_methods, 0);
  luaL_getmetatable(L, "userInfoMeta");
  lua_setmetatable(L, -2);

return 1;
}

// I have binded newUserInfo to the createUserInfo method.
// I have also created the metatable for this userInfo Object in the init method.
// luaL_newmetatable(L, "userInfoMeta");
// lua_pushstring(L, "__index");
// lua_pushvalue(L, -2);
// lua_settable(L, -3);
// luaL_register(L, NULL, userInstance_methods);    

Please let me know if I am missing anything!

My LuaCode snippet:

local library = require('plugin.user')

local userInfo = library.newUserInfo()
print(userInfo.getUserName())

Update I got rid of null, after using lua_upvalueindex(1) This is giving reference back to the user info instance.

UserInfo **userInfo = (UserInfo**)lua_touserdata(L,lua_upvalueindex( 1 ));

Hope it helps others too!

like image 800
kapser Avatar asked Sep 03 '13 12:09

kapser


1 Answers

I think it may be the way your dealing with the userdata's metatable. Specifically, I think what you're returning from createUserInfo() is a table not a userdata. What I suggest is that you create the metatable once e.g. in luaopen, and then just set that on the new userdata. Something like this...

int createUserInfo(lua_State *L) {

  UserInfo *userInfo = [[UserInfo alloc] init];
  UserInfoData **userInfoData = (UserInfoData **)lua_newuserdata(L, sizeof(userInfo));
  *userInfoData = userInfo;

  luaL_getmetatable(L, "userInfoMeta");
  lua_setmetatable(L, -2);

  return 1;
}

LUALIB_API int luaopen_XXX(lua_State *L)
{
    luaL_newmetatable(L,"userInfoMeta");
    luaL_openlib(L, NULL, userInstance_methods, 0);
    lua_pushvalue(L, -1);
    lua_setfield(L, -2, "__index");
    ...
like image 113
Alex Avatar answered Oct 17 '22 06:10

Alex