• Subject: Re: Pushing a UserData pointer?
• From: Ben Sunshine-Hill <sneftel@...>
• Date: Mon, 16 May 2005 12:13:39 -0700

On 5/16/05, Chris Marrin <chris@marrin.com> wrote:
> Am I missing something in the public API, or is there really no more
> efficient way to move between C++ and Lua?

Wellllll.

\begin{hack}
If you know that a particular object is being stored in a userdata,
you CAN refer to it as a userdata. All it takes is some pointer
arithmetic.

Ya see, a userdata, as allocated on the heap, consists of a struct
Udata (well, actually a union Udata, but only for alignment purposes;
treat it as a struct) followed by an arbitrary amount of data. The
struct portion is a GCable object, which can be set into a stack
position with setuvalue (a macro defined in lobject.h). This function,
therefore, should work, though it's untested. Written based on the
5.0.2 source. (You will, of course, need to modify the include to
correctly penetrate into the internals of Lua; lobject.h is not a

#include <lobject.h>
void pushexistinguserdata(lua_State *L, void *ud)
{
lua_lock(L);
u = luaS_newudata(L, size);
setuvalue(L->top, ((Udata*)ud)-1);
api_incr_top(L);
lua_unlock(L);
}

If you call this with a pointer that is not actually a pointer to a
preexisting userdata, horrible horrible things will happen within the
GC. Use with caution and revulsion.

\end{hack}

Ben