lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Fri, Sep 21, 2001 at 05:56:26PM -0700, Brian Hook wrote:
> I want to pass a pointer into Lua.  It looks like lua_pushusertag() is
> the way to go.  I'm really unclear what "tag" is supposed to do.  Is it
> because Lua can't differentiate between two different user data items
> with the same value, and the tag is used to differentiate between them?
> 
> All I'm trying to do is set a global variable to hold a pointer to some
> data.  Lua doesn't access it, it simply passes the pointer BACK to the
> application when necessary.  Granted, I could skip over this on the C
> side, but either way I'd like to know the right way to do this from
> C->Lua.

If this is all you need to do, then you don't need to worry about the
tag mechanism at all. In this case, you can simply use LUA_ANYTAG or
the tag 0. For your purposes these two should be absolutely equivalent
(although using tag 0 directly might be a bit faster; I don't know for
sure).

The tag only comes into play when you want to manipulate the data from
Lua (see also the chapter on tag methods in the
documentation). Basically, these allow you to give userdata unique
type semantics in Lua. These could mimic a builtin type in Lua, such
as a table, or as numbers with arithmetic operations, or something
completely different. It all depends on what you want and what you
need. Sometimes using tag methods is very similar to what you do when
you overload operators in C++ for a user-defined class.

For example, suppose that you define a struct in C like this:

struct X {
  int a;
  float b;
};

Now suppose that you want to be able to read and manipulate these
structs from Lua. Then the first thing you would do is create a new,
unique tag to give to data of type struct X:

xtag = lua_newtag(L);

Then you can use this tag whenever you make userdata of type struct X
available to lua:

struct X *x = malloc(sizeof (struct X));
lua_pushusertag(L, x, xtag);
lua_setglobal(L, "sx");

If you now define and implement the "gettable" and "settable" tag
methods for xtag appropriately in C, you can write the following in
lua to read and change the values of any object of type struct X:

sx["a"] = 123   (calls settable tag method for xtag)
sx["b"] = -1.5  (calls settable tag method for xtag)
sx.a =  234     (calls settable tag method for xtag)
print(sx.b)     (calls gettable tag method for xtag)

and so on.

This mechanism is very powerful, and aside from its general
usefulness, it potentially allows you to inspect any C or C++ object
from lua, which can be an invaluable debugging aid. For the latter,
the tolua program can do most of the work of creating the bindings for
you, by the way.

I find that it helps to think of tags this way: Tags are to Lua what
user-defined types are to other programming languages. In lua 4.0 this
connection is not explicit, but from what I've heard it is supposed to
be much more explicit in lua 4.1.

I hope that things are a little clearer now. Feel free to ask if you
need additional clarification.

- Christian