lua-users home
lua-l archive

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

At work, we use in our product a proprietary DLL provided by our client, to
access their address book (AB).
We only have the binary and a few headers for the API (and some doc).

So I had the idea to make a Lua interpreter using this API, so I can play
with it and do some prototypes, to see what I can do and cannot do.
I finally chose to use the Lua 4.0 interpreter, being a bit simplier (?) and
more stable (at least regarding the API) that the 5.0 version.

Since the behavior of my library is quite similar to fopen/fread/fclose, I
took a hard look at the implementation of liolib.c.
So I call an init function to get a handle to an address book, use this
handle in all function calls, and finally close the handle when done.

Like in iolib, I created two tags, one to mark the active handles (to
currently opened AB), and one to mark the inactive handles (on which close have
been called, but which are not yet unreferenced).
I have set a tag method for the GC so it collects active handles without
reference, either because the program does a "handle = nil" without closing the
handle first, or on the call of lua_close (which I made mandatory unless I
give the -k (quick) option).

So far, it seems to work fine. :-)
I have two questions about the iolib implementation.


First, the short one.
As I said, when I close a handle, I change its tag. I use the same method as
in iolib:

 * Change the tag of the closed handle,
 * so the garbage collector will ignore it.
void CloseAb(
	lua_State *L,
	/* Push the userdata on the stack. Since Lua already have this UD,
	 * it will push it (no creation).
    lua_pushusertag(L, pAH, abHandleTag);
	/* Change the tag of the UD on the stack */
    lua_settag(L, closedHandleTag);

The comments are mine :-) Based on the Lua doc (a bit terse on userdata...).
I call this function inside my close() wrapper, after having called the
close() API function.

But actually, I don't understand how this work, perhaps I missed something
in the code.
Once this userdata is pushed on the stack, what does it do there? Do I have
to pop it out?
How this affects actually the real userdata? I am lost.


The second question is about the way data for functions with control is

I saw that iolib uses the IOCtrl structure to allow passing global values to
each function having a file handle as parameter, using upvalues (closures)
to do it cleanly.
It may be an overkill (beside the aesthetical question) because these values
are unlikely to change between states and/or threads.

For the sake of simplicity, since my library will be alone (beside the
standard libraries), I have put the two tags in global variables.

I know that global variables are often seen as evil these days: they pollute
the namespace, so they may clash with other libraries, they can be changed
by a function as a side effect, they can hurt the use of multithreading (each
thread may need to have its separate, distinct value).

These are non-issues in my case, where there will be no other library,
running in single thread and mono-state, and I am sure not to change these values
(I control what I do).

My question is actually: I am wrong to use global variables here? Are there
other issues I overlooked and should take in account?

Thank you.


Philippe Lhoste (Paris -- France)
Professional programmer and amateur artist

GMX - Die Kommunikationsplattform im Internet.