1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!--Converted with LaTeX2HTML 2002-2-1 (1.71)
original version by: Nikos Drakos, CBLU, University of Leeds
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
* with significant contributions from:
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
<HTML>
<HEAD>
<TITLE>3 The Lua interface</TITLE>
<META NAME="description" CONTENT="3 The Lua interface">
<META NAME="keywords" CONTENT="ionnotes">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="LaTeX2HTML v2002-2-1">
<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
<LINK REL="STYLESHEET" HREF="ionnotes.css">
<LINK REL="next" HREF="node5.html">
<LINK REL="previous" HREF="node3.html">
<LINK REL="up" HREF="ionnotes.html">
<LINK REL="next" HREF="node5.html">
</HEAD>
<BODY >
<DIV CLASS="navigation"><!--Navigation Panel-->
<A NAME="tex2html114"
HREF="node5.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A>
<A NAME="tex2html108"
HREF="ionnotes.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A>
<A NAME="tex2html102"
HREF="node3.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A>
<A NAME="tex2html110"
HREF="node1.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A>
<A NAME="tex2html112"
HREF="node8.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A>
<BR>
<B> Next:</B> <A NAME="tex2html115"
HREF="node5.html">4 Miscellaneous design notes</A>
<B> Up:</B> <A NAME="tex2html109"
HREF="ionnotes.html">Ion: Notes for the</A>
<B> Previous:</B> <A NAME="tex2html103"
HREF="node3.html">2 Object system implementation</A>
<B> <A NAME="tex2html111"
HREF="node1.html">Contents</A></B>
<B> <A NAME="tex2html113"
HREF="node8.html">Index</A></B>
<BR>
<BR></DIV>
<!--End of Navigation Panel-->
<!--Table of Child-Links-->
<A NAME="CHILD_LINKS"><STRONG>Subsections</STRONG></A>
<UL CLASS="ChildLinks">
<LI><A NAME="tex2html116"
HREF="node4.html#SECTION00041000000000000000"><SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">1</SPAN> Supported types</A>
<LI><A NAME="tex2html117"
HREF="node4.html#SECTION00042000000000000000"><SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">2</SPAN> Exporting functions</A>
<LI><A NAME="tex2html118"
HREF="node4.html#SECTION00043000000000000000"><SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">3</SPAN> Calling Lua functions and code</A>
<LI><A NAME="tex2html119"
HREF="node4.html#SECTION00044000000000000000"><SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">4</SPAN> Miscellaneous notes</A>
</UL>
<!--End of Table of Child-Links-->
<HR>
<H1><A NAME="SECTION00040000000000000000">
<SPAN CLASS="arabic">3</SPAN> The Lua interface</A>
</H1>
<P>
This section finally describes the implementation details and how modules
should us the Lua interface. First, in section <A HREF="#sec:supptypes">3.1</A>
we look at types supported by the interface, how objects are passed to Lua
code and how Lua tables should be accessed from Ion and modules. In section
<A HREF="#sec:exporting">3.2</A> the methods for exporting functions and how they
are called from Lua are explained and in section <A HREF="#sec:calling">3.3</A> the
method for calling Lua functions is explained.
<P>
<H2><A NAME="SECTION00041000000000000000"></A>
<A NAME="sec:supptypes"></A>
<BR>
<SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">1</SPAN> Supported types
</H2>
<P>
The following types are supported in passing parameters between the
C side of Ion and Lua:
<P>
<TABLE CELLPADDING=3 BORDER="1">
<TR><TD ALIGN="RIGHT">Identifier
character</TD>
<TD ALIGN="LEFT">C type</TD>
<TD ALIGN="LEFT">Description</TD>
</TR>
<TR><TD ALIGN="RIGHT">i</TD>
<TD ALIGN="LEFT">int</TD>
<TD ALIGN="LEFT">Integer</TD>
</TR>
<TR><TD ALIGN="RIGHT">s</TD>
<TD ALIGN="LEFT">char*</TD>
<TD ALIGN="LEFT">String</TD>
</TR>
<TR><TD ALIGN="RIGHT">S</TD>
<TD ALIGN="LEFT">const char*</TD>
<TD ALIGN="LEFT">Constant string</TD>
</TR>
<TR><TD ALIGN="RIGHT">d</TD>
<TD ALIGN="LEFT">double</TD>
<TD ALIGN="LEFT"> </TD>
</TR>
<TR><TD ALIGN="RIGHT">b</TD>
<TD ALIGN="LEFT">bool</TD>
<TD ALIGN="LEFT"> </TD>
</TR>
<TR><TD ALIGN="RIGHT">t</TD>
<TD ALIGN="LEFT">ExtlTab<A NAME="525"></A></TD>
<TD ALIGN="LEFT">Reference to Lua table</TD>
</TR>
<TR><TD ALIGN="RIGHT">f</TD>
<TD ALIGN="LEFT">ExltFn<A NAME="526"></A></TD>
<TD ALIGN="LEFT">Reference to Lua function.</TD>
</TR>
<TR><TD ALIGN="RIGHT">o</TD>
<TD ALIGN="LEFT">Any WObj*</TD>
<TD ALIGN="LEFT"> </TD>
</TR>
</TABLE>
<P>
The difference between identifiers 's' and 'S' is that constant
strings as return values are not free'd by the level 1 call handler
(see below) after passing to Lua (<TT>lua_pushstring</TT> always makes a
copy) unlike normal strings. String parameters are always assumed to be
the property of the caller and thus implicitly const.
<P>
Likewise, if a reference to 't' or 'f' is wished to be stored
beyond the lifetime of a function receiving such as an argument, a new
reference should be created with <TT>extl_ref_table</TT>/<TT>fn</TT>.
References can be free'd with
<TT>extl_unref_table</TT>/<TT>fn</TT>. References gotten as return values with
the <TT>extl_table_get</TT> (how these work should be self-explanatory!)
functions are property of the caller and should be unreferenced with the
above-mentioned functions when no longer needed.
The functions <TT>extl_fn</TT>/<TT>table_none()</TT>
return the equivalent of NULL.
<P>
WObjs are passed to Lua code with WWatch userdatas pointing to
them so the objects can be safely deleted although Lua code might still be
referencing them. (This is why SWIG or tolua would not have helped in
creating the interface: extra wrappers for each function would still
have been needed to nicely integrate into Ion's object system. Even in
the case that Ion was written in C++ this would be so unless extra bloat
adding pointer-like objects were used everywhere instead of pointers.)
It may be sometimes necessary check in Lua code that a value known to
be an Ion WObj is of certain type. This can be accomplished with
<TT>obj_is(obj, "typename")</TT>. <TT>obj_typename(obj)</TT> returns type
name for a WObj.
<P>
<H2><A NAME="SECTION00042000000000000000"></A>
<A NAME="sec:exporting"></A>
<BR>
<SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">2</SPAN> Exporting functions
</H2>
<P>
Exported functions (those available to the extension language) are
defined by placing <TT>EXTL_EXPORT</TT> before the function implementation
in the C source. The script mkexports.pl is then used to automatically
generate <SPAN CLASS="textit">exports.c</SPAN> from the source files if
<TT>MAKE_EXPORTS=modulename</TT>
is specified in the Makefile. All pointers with type beginning with a 'W'
are assumed to be pointers to something inheriting WObj. In
addition to a table of exported functions and second level call handlers
for these, <SPAN CLASS="textit">exports.c</SPAN> will contain two functions
<TT>module_register_exports()</TT> and
<TT>module_unregister_exports()</TT> that should then be called in module
initialisation and deinitialisation code.
<P>
You've seen the terms level 1 and 2 call handler mentioned above.
<A NAME="495"></A>
The Lua support code uses two so called call handlers to convert and check
the types of parameters passed from Lua to C and back to Lua. The first
one of these call handlers is the same for all exported functions and
indeed lua sees all exported as the same C function (the L1 call handler)
but with different upvalues passing a structure describing the actual
function and the second level call handler. The L1 call handler checks
that the parameters received from Lua match a template given as a string
of the identifier characters defined above. If everything checks out ok,
the parameters are then put in an array of C unions that can contain
anyof these known types and the L2 call handler is called.
<P>
The L2 call handler (which is automatically generated by the mkexports.pl
script) for each exported function checks that the passed WObjs
are of the more refined type required by the function and then calls the
actual function. While the WObj checking could be done in the L1 handler
too, the L2 call handlers are needed because we may not know how the target
platform passes each parameter type to the called function. Thefore we
must let the C compiler generate the code to convert from a simple and
known enough parameter passing method (the unions) to the actual
parameter passing method. When the called function returns everything
is done in reverse order for return values (only one return value is
supported by the generated L2 call handlers).
<P>
<H2><A NAME="SECTION00043000000000000000"></A>
<A NAME="sec:calling"></A>
<BR>
<SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">3</SPAN> Calling Lua functions and code
</H2>
<P>
The functions
<TT>extl_call</TT><A NAME="519"></A>,
<TT>extl_call_named</TT><A NAME="520"></A>,
<TT>extl_dofile</TT><A NAME="521"></A> and
<TT>extl_dostring</TT><A NAME="522"></A>
call a referenced function (ExtlFn), named function, execute a
string and a file, respectively. The rest of the parameters for all these
functions are similar. The 'spec' argument is a string of identifier
characters (see above) describing the parameters to be passed. These
parameters follow after 'rspec'. For dofile and dostring these parameters
are passed in the global table arg (same as used for program command
lien parameters) and for functions as you might expect. The parameter
'rspec' is a similar description of return values. Pointers to variables
that should be set to the return values follow after the input values.
The return value of all these functions tells if the call and parameter
passing succeeded or not.
<P>
Sometimes it is necessary to block calls to all but a limited set of
Ion functions. This can be accomplished with
<TT>extl_set_safelist</TT><A NAME="523"></A>.
The parameter to this function is a NULL-terminated array of strings
and the return value is a similar old safelist.
The call <TT>extl_set_safelist(NULL)</TT> removes any safelist and allows
calls to all exported functions.
<P>
<H2><A NAME="SECTION00044000000000000000">
<SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">4</SPAN> Miscellaneous notes</A>
</H2>
<P>
Configuration files should be read as before with the function
<TT>read_config_for</TT><A NAME="524"></A>
except that the list of known options is no longer present.
<P>
Winprops are now stored in Lua tables and can contain arbitrary
properties. The 'proptab' entry in each WClientWin is a reference
to a winprop table or <TT>extl_table_none()</TT> if such does not exist
and properties may be read with the <TT>extl_table_gets</TT> functions.
(It is perfectly legal to pass <TT>extl_table_none()</TT> references to
<TT>extl_table_get*</TT>.)
<P>
<DIV CLASS="navigation"><HR>
<!--Navigation Panel-->
<A NAME="tex2html114"
HREF="node5.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A>
<A NAME="tex2html108"
HREF="ionnotes.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A>
<A NAME="tex2html102"
HREF="node3.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A>
<A NAME="tex2html110"
HREF="node1.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A>
<A NAME="tex2html112"
HREF="node8.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A>
<BR>
<B> Next:</B> <A NAME="tex2html115"
HREF="node5.html">4 Miscellaneous design notes</A>
<B> Up:</B> <A NAME="tex2html109"
HREF="ionnotes.html">Ion: Notes for the</A>
<B> Previous:</B> <A NAME="tex2html103"
HREF="node3.html">2 Object system implementation</A>
<B> <A NAME="tex2html111"
HREF="node1.html">Contents</A></B>
<B> <A NAME="tex2html113"
HREF="node8.html">Index</A></B> </DIV>
<!--End of Navigation Panel-->
</BODY>
</HTML>
|