I have been trying to wrap my head around it for some time now, but I can't seem to find any tutorials/explanations that I really understand.
Why do you need them, why can't you just directly bind C functions to Lua metatables?
The type userdata is provided to allow arbitrary C data to be stored in Lua variables. A userdata value is a pointer to a block of raw memory. There are two kinds of userdata: full userdata, where the block of memory is managed by Lua, and light userdata, where the block of memory is managed by the host.
Any data the user creates or owns. The term user data may be used to emphasize that the data were created and owned by the user. For example, when deleting an application, an uninstall program may ask if user data is also to be deleted.
A userdata is a garbage-collected value of an arbitrary size and content. You create one from the C API, with lua_newuserdata()
, which creates and pushes it on the stack and gives you a pointer to its content to initialize as you see fit from C.
It is very comparable to calling malloc()
. A key distinction from malloc()
is that you never need to call free()
, rather you just allow the last reference to it to evaporate and the garbage collector will reclaim its storage eventually.
They are most useful for holding data that is useful from C, but which must be managed from Lua. They support individual metatables, which are the key feature that allows binding C or C++ objects to Lua. You simply populate its metatable with methods written in C that access, modify, and/or use the content of the userdata, and the result is an object that is accessible from Lua. A good example of this is the io
library, which stores C FILE *
pointers in userdata, and provides bindings that implement the familiar read
, write
and similar methods. By implementing an __gc
metamethod, the io
library makes sure that one of its file
objects closes the associated FILE *
when it is collected.
A light userdata is how you represent a pointer to something as a value in Lua. You create one by calling lua_pushlightuserdata()
with the pointer that is its value. They are managed by Lua much the same way that a number is. They are useful when you need to name a C object in a way that the name can be passed around within Lua, but the object's lifetime is not managed by Lua. Like numbers are equal when they have the same value, light userdata compare equal when they hold the same pointer. Like numbers, they exist as long as they are on the stack or stored in a variable, and they do not have individual metatables and they are not garbage collected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With