Imagine the following code:
Mytable={}
print(Mytable)
Prints something like Table: 12345
.
How do I get the "address" part from Lua without messing with tostring
's return value, and more importantly, how do I get the table back?
In code:
addr=table2address(Mytable)
-- type(addr) is number, addr is 12345
Othertable=address2table(addr)
-- type(Othertable) is table, Othertable==Mytable is true (same reference)
Is there any way to implement these 2 functions in Lua? If not, (how) do I do this in C?
Edit: the table2address
could be done by cutting the Table:
off from tostring(Mytable)
, but only if metamethod __tostring
isn't defined, so I want to avoid this.
A trivial implementation meets all your criteria but one:
function table2address(Mytable) return Mytable end
function address2table(addr) return addr end
demo:
> Mytable={}
> print(Mytable)
table: 0x7fe511c0a190
> addr = table2address(Mytable)
> Othertable=address2table(addr)
> =type(Othertable)
table
> print(Othertable==Mytable)
true
A slightly more complicated implementation meets all your criteria:
t2at = {}
function table2address(Mytable)
local addr = t2at[Mytable]
if addr == nil then
addr = #t2at + 1
t2at[Mytable] = addr
t2at[addr] = Mytable
end
return addr
end
function address2table(addr)
return t2at[addr]
end
demo:
> Mytable={}
> addr = table2address(Mytable)
> Othertable=address2table(addr)
> =type(Othertable)
table
> print(Othertable==Mytable)
true
> =type(addr)
number
So, why is the address important to you?
In a garbage collected language such as Lua, it is only possible to hold a reference to an object, not an address. [The present implementation may or may not move objects during GC, but other than userdata
and Lua states, Lua has license to move anything.]
ADDENDUM
Re: "the addresses never get randomized (try print({}) in 2 new interactive lua instances)"
e$ lua
Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio
> print({})
table: 0x7fdaca4098c0
> ^D
e$ lua
Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio
> print({})
table: 0x7fb02a4098c0
> ^D
e$
Re: the physical address is really needed
Look at the function luaL_tolstring
that implements the guts of print; it has (in Lua 5.2.2):
default:
lua_pushfstring(L, "%s: %p", luaL_typename(L, idx),
lua_topointer(L, idx));
break;
So, lua_topointer(L, idx)
is the function you need to get a table's address.