continuing an old thread... I don't remember if anybody suggested solution for Chris question that was stable on (hypothetical) memory compacting GC and at the same time allowed for easy pointer comparison; but this is what i've just tried: /*--------- string equality helper ------------*/ static int myStatKey; static void regString (lua_State *L, const char *s) { lua_pushlightuserdata (L, myStatKey); lua_gettable (L, LUA_REGISTRYINDEX); if (lua_isnil (L, -1)) { lua_pop (L, 1); lua_newtable (L); lua_pushlightuserdata (L, myStatKey); lua_pushvalue (L, -2); lua_settable (L, LUA_REGISTRYINDEX); } lua_pushstring (L, s); lua_pushlightuserdata (L, s); lua_settable (L, -3); } static const char *toStringReg (lua_State *L, int n) { const char *r = NULL; lua_pushlightuserdata (L, myStatKey); lua_gettable (L, LUA_REGISTRYINDEX); if (lua_isnil (L, -1)) { lua_pop (L, 1); return NULL; } lua_pushvalue (L, n); lua_gettable (L, -2); r = lua_touserdata (L, -1); lua_pop (L, 1); return r; } /*------ end --------*/ the static int variable is used as a key in the registry, to avoid collisions. to use it, just register any constant string you'd like to use (at module initialization time): regString (L, "foo"); regString (L, "bar"); and, in your __index() metamethod (or anywhere you'd like to test a Lua string against several C strings), first convert it to the registered pointer: const char *k = *toStringReg (L, n); /* n is a stack position */ if (k == "foo") { do_something (); } else if (k == "bar") { do_someelse (): } else { not_found (); } of course, this depends on the compiler optimizing equal constant strings to the same location in memory. a little variation would be to store small integers (from an enum type) instead of the const char pointers. this would make possible to use switch(getreg(L,n)) {.....} -- Javier
Attachment:
pgpBYSdUL72pK.pgp
Description: PGP signature