lua-users home
lua-l archive

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


The only thing I have to do to export a function to Lua is to preface it
with

LUA_EXPORT.  This is #defined as __declspec(__dllexport)

Which, when you are using VC++ means to put the function declaration in the
export table.

I then parse the binary image of the executable at run time and extract all
of the functions that are exported, demangle their names, and use this
information, not only to call the C++ function from Lua, but to insure they
are called in a type-safe way, even for userdata/void* data.  This idea was
first proposed and written by Scott Bilas.  For a good reference, see FuBi
at http://members.aa.net/~scottb/gdc/ .  There is good documentation and
code describing how to do this at the aforementioned URL.

This is just the executable image file end of things and does not include
interfacing with Lua, but the interfacing is the straight-forward part.

For class member function calls, I pass the pointer/handle to the object as
the first parameter, then, if it is the correct type of "this" pointer, I
make the function call directly, by hand loading the stack and the this
pointer and jumping the function directly.  (see the above reference for how
to do this.)

I manage type safe pointers by keeping a string representation of the type
of every parameter and return value in every function being used by Lua.  I
get this information for free when I parse the executable image.  When I
return a userdata type to Lua, I keep track of the pointer value and the
string in a map.  When I get that pointer back as an argument, I compare the
string value of the returned value, with the string value of the parameter
type I am expecting, and make sure they match.  The one big problem with
this is that it does not properly handle polymorphism.  (you can't call a
base class member function with a derived class handle/"this"_pointer).  We
have worked around this so far.

Lastly, the unified function handler.  This is the meat of the interface.
The first thing you need to do, is to register every C++ function that you
want to access from Lua to the same function, then, when the function is
called, you need to get the name of the function.  I am pretty sure I did
this the wrong way, by hacking some code in to Lua.  I have heard that this
information is available through the debugging interface.  If anyone could
tell me how, I would appreciate it.  Then, I look the function up in my
function database, validate all of the parameters and the return value, hand
load the call stack, and jump to the function in memory.

This is probably a lot more than you wanted.  Hopefully there is some useful
in information here though.

--jnw

----- Original Message -----
From: "J. Perkins" <jason@379.com>
To: "Multiple recipients of list" <lua-l@tecgraf.puc-rio.br>
Sent: Wednesday, August 29, 2001 8:50 AM
Subject: Re: The Lua C API


> Jens Wessling wrote:
> > We have a lot of other nice Lua integration features.
> > 1) Auto registration of C++ functions.
> > 2) Ability to call class member functions from Lua.
> > 3) Type safe pointer passing to and from Lua
> > 4) Unified C++ function handler for C++ calls made from Lua.
>
> Could you talk a little more about (1)? Currently I have
> to precede each scriptable C++ function with a couple of
> macros to register it with Lua. If you've found a way to
> make this more transparent I'd love to hear it.
>
> Jason
>