Calling from C through lua to another C function

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Calling from C through lua to another C function

Steve Heller
Hi all,

I'm a total newbie to lua, although I have a lot of
experience in other languages, notably C++.

I'm sure what I'm trying to do is simple if you know
how to do it, but I don't, so I've been floundering
around for several days with it.

Here's the problem. I have a number of C++ objects
that have member functions that I need to be able to
access from lua. To make this possible, I need to pass
a pointer to one of the objects from the calling C++
program through lua into C++ again. My plan was to
pass the pointer via light userdata through the lua
program out to a lower level C++ static member
function which will then cast it back to the right
type (which I will always know) and call the
appropriate function.

I know this is possible, but I've been unable to
figure out exactly how to do it. Does anyone have a
complete example that actually compiles and runs? It
doesn't have to be anything fancy; just passing a
light user data value from C through lua back to C
will do the job.

Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: Calling from C through lua to another C function

Mildred Ki'Lya

On Sun, 30 Apr 2006 10:57:12 -0700 (PDT) Steve Heller wrote:
> I know this is possible, but I've been unable to
> figure out exactly how to do it. Does anyone have a
> complete example that actually compiles and runs? It
> doesn't have to be anything fancy; just passing a
> light user data value from C through lua back to C
> will do the job.

What's wrong with the manual ?

int create_pointer(lua_State* L) {
        mytype* p = NULL;
        lua_pushlightuserdata(L, (void*) p);
        return 1; // the userdata
}

int access_pointer(lua_State* L) {
        luaL_checkany(L, 1);
        mytype* p = (mytype*) lua_touserdata (L, 1);
        return 0;
}

Is that what you want ?

Not tested but should work.
I suggest you to use full userdata because these can be garbage
collected (and so let you free memory) and assigned to metatables. If
you use full userdata, you must then deal with mytype**

Example:

int create_pointer(lua_State* L) {
        mytype** p = lua_newuserdata(L, sizeof(mytype*));
        *p = NULL;
        { // optional
                if(luaL_newmetatable(L, "metatable_unique_name")) {
                        // the metatable isn't created yet
                        // it is pushed on the stack, populate it
                }
                // STACK: userdata, metatable
                lua_setmetatable(L, -2);
                // STACK: userdata
        }
        return 1; // the userdata
}

int access_pointer(lua_State* L) {
        mytype* p = *((mytype**)
                luaL_checkudata(L, 1, "metatable_unique_name"));
        // do what you want with p here
        return 0;
}

Not tested but should work :)

Mildred

--
Mildred       <xmpp:[hidden email]> <http://mildred632.free.fr/>
Clef GPG :    <hkp://pgp.mit.edu> ou <http://mildred632.free.fr/gpg_key>
Fingerprint : 197C A7E6 645B 4299 6D37 684B 6F9D A8D6 [9A7D 2E2B]