1
votes

I'm working with Lua/C bindings and am having an issue with objects stored in a lua table that are light user data. In the example below, I'm calling 'myfunction' from C with some data that is then used to allocate a new object (in C) via my function "net.connection(v)", which uses lua_newuserdata() to return the object result. I try to use this value as a key into a table 'mytable'. When I call 'myfunction', create my new object, and store it in my table, it appears to be fine, as the value I store into the table is what the 'print' gives me.

mytable = {}

function action(obj)
  print(mytable[obj])
end

function myfunction(data)
  for k,v in pairs(data) do
    theObj = net.connection(v)
    mytable[theObj] = "test string"
    print(mytable[theObj]) --Prints 'test string'
  end
end

However, at a later point in time, I want to look up this data using the same object pointer (function 'action' above), but always get nil. The pointer addresses of (theObj and obj) are the same, and when I print out the contents of the table (keys, values) it appears that the table contains both a pointer to my userdata and the proper value, but when I use the argument (obj), I can't retrieve a value from the table. In the case of the function 'action', I'm pushing the user data onto the stack with push_lightuserdata.

Are there any subtleties to using push_lightuserdata in this way that could be causing this issue?

Accoring to this link, using light user data as a table key is fine...

1
Just to clarify, when you do something like for k, v in pairs(mytable) do print(k, v) end you can see the key value pair you want, but when you call action with what appears to be the appropriate key, you get nil? Or are you trying to get to the value in mytable from C code not posted here? - Alex
You're correct. I can see the key, value pair I want when iterating over the table in 'action', but when I try to get the value using the parameter as the key it gives me a nil result. - jimt
Have you tried double checking the key with print(obj) directly inside action to make sure it's getting the value you expect? If there's not a lot of other key value pairs in the table, I might try adding something like this: for k, v in pairs(mytable) do if k == obj then print(k, v, "Found it!") else print(k, v) end. Using light user data as keys should be fine, so there has to be a silly mistake here somewhere. :-/ - Alex
Yeah, I've done that, and get something like this: (userdata: 0x6e8ca94) userdata: 0x7c71704 test_string userdata: 0x6e8ca94 test_string userdata: 0x7c66434 test_string - jimt

1 Answers

4
votes

Userdata and light userdata are two distinct types in Lua. You are putting a userdata in the table as the key, and then trying to find it with a light userdata. That won't work. You need to use the same types.

Since you are creating the net.connection as a userdata, you'll need to keep it in a table somewhere so you can find it later from C.