ext_ffi_tutorial.html (22557B)
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 2 <html> 3 <head> 4 <title>FFI Tutorial</title> 5 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 6 <meta name="Author" content="Mike Pall"> 7 <meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall"> 8 <meta name="Language" content="en"> 9 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> 10 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> 11 <style type="text/css"> 12 table.idiomtable { font-size: 90%; line-height: 1.2; } 13 table.idiomtable tt { font-size: 100%; } 14 table.idiomtable td { vertical-align: top; } 15 tr.idiomhead td { font-weight: bold; } 16 td.idiomlua b { font-weight: normal; color: #2142bf; } 17 </style> 18 </head> 19 <body> 20 <div id="site"> 21 <a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a> 22 </div> 23 <div id="head"> 24 <h1>FFI Tutorial</h1> 25 </div> 26 <div id="nav"> 27 <ul><li> 28 <a href="luajit.html">LuaJIT</a> 29 <ul><li> 30 <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> 31 </li><li> 32 <a href="install.html">Installation</a> 33 </li><li> 34 <a href="running.html">Running</a> 35 </li></ul> 36 </li><li> 37 <a href="extensions.html">Extensions</a> 38 <ul><li> 39 <a href="ext_ffi.html">FFI Library</a> 40 <ul><li> 41 <a class="current" href="ext_ffi_tutorial.html">FFI Tutorial</a> 42 </li><li> 43 <a href="ext_ffi_api.html">ffi.* API</a> 44 </li><li> 45 <a href="ext_ffi_semantics.html">FFI Semantics</a> 46 </li></ul> 47 </li><li> 48 <a href="ext_jit.html">jit.* Library</a> 49 </li><li> 50 <a href="ext_c_api.html">Lua/C API</a> 51 </li><li> 52 <a href="ext_profiler.html">Profiler</a> 53 </li></ul> 54 </li><li> 55 <a href="status.html">Status</a> 56 <ul><li> 57 <a href="changes.html">Changes</a> 58 </li></ul> 59 </li><li> 60 <a href="faq.html">FAQ</a> 61 </li><li> 62 <a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a> 63 </li><li> 64 <a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a> 65 </li><li> 66 <a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a> 67 </li></ul> 68 </div> 69 <div id="main"> 70 <p> 71 This page is intended to give you an overview of the features of the FFI 72 library by presenting a few use cases and guidelines. 73 </p> 74 <p> 75 This page makes no attempt to explain all of the FFI library, though. 76 You'll want to have a look at the <a href="ext_ffi_api.html">ffi.* API 77 function reference</a> and the <a href="ext_ffi_semantics.html">FFI 78 semantics</a> to learn more. 79 </p> 80 81 <h2 id="load">Loading the FFI Library</h2> 82 <p> 83 The FFI library is built into LuaJIT by default, but it's not loaded 84 and initialized by default. The suggested way to use the FFI library 85 is to add the following to the start of every Lua file that needs one 86 of its functions: 87 </p> 88 <pre class="code"> 89 local ffi = require("ffi") 90 </pre> 91 <p> 92 Please note this doesn't define an <tt>ffi</tt> variable in the table 93 of globals — you really need to use the local variable. The 94 <tt>require</tt> function ensures the library is only loaded once. 95 </p> 96 <p style="font-size: 8pt;"> 97 Note: If you want to experiment with the FFI from the interactive prompt 98 of the command line executable, omit the <tt>local</tt>, as it doesn't 99 preserve local variables across lines. 100 </p> 101 102 <h2 id="sleep">Accessing Standard System Functions</h2> 103 <p> 104 The following code explains how to access standard system functions. 105 We slowly print two lines of dots by sleeping for 10 milliseconds 106 after each dot: 107 </p> 108 <pre class="code mark"> 109 <span class="codemark"> 110 ① 111 112 113 114 115 116 ② 117 ③ 118 ④ 119 120 121 122 ⑤ 123 124 125 126 127 128 ⑥</span>local ffi = require("ffi") 129 ffi.cdef[[ 130 <span style="color:#00a000;">void Sleep(int ms); 131 int poll(struct pollfd *fds, unsigned long nfds, int timeout);</span> 132 ]] 133 134 local sleep 135 if ffi.os == "Windows" then 136 function sleep(s) 137 ffi.C.Sleep(s*1000) 138 end 139 else 140 function sleep(s) 141 ffi.C.poll(nil, 0, s*1000) 142 end 143 end 144 145 for i=1,160 do 146 io.write("."); io.flush() 147 sleep(0.01) 148 end 149 io.write("\n") 150 </pre> 151 <p> 152 Here's the step-by-step explanation: 153 </p> 154 <p> 155 <span class="mark">①</span> This defines the 156 C library functions we're going to use. The part inside the 157 double-brackets (in green) is just standard C syntax. You can 158 usually get this info from the C header files or the 159 documentation provided by each C library or C compiler. 160 </p> 161 <p> 162 <span class="mark">②</span> The difficulty we're 163 facing here, is that there are different standards to choose from. 164 Windows has a simple <tt>Sleep()</tt> function. On other systems there 165 are a variety of functions available to achieve sub-second sleeps, but 166 with no clear consensus. Thankfully <tt>poll()</tt> can be used for 167 this task, too, and it's present on most non-Windows systems. The 168 check for <tt>ffi.os</tt> makes sure we use the Windows-specific 169 function only on Windows systems. 170 </p> 171 <p> 172 <span class="mark">③</span> Here we're wrapping the 173 call to the C function in a Lua function. This isn't strictly 174 necessary, but it's helpful to deal with system-specific issues only 175 in one part of the code. The way we're wrapping it ensures the check 176 for the OS is only done during initialization and not for every call. 177 </p> 178 <p> 179 <span class="mark">④</span> A more subtle point is 180 that we defined our <tt>sleep()</tt> function (for the sake of this 181 example) as taking the number of seconds, but accepting fractional 182 seconds. Multiplying this by 1000 gets us milliseconds, but that still 183 leaves it a Lua number, which is a floating-point value. Alas, the 184 <tt>Sleep()</tt> function only accepts an integer value. Luckily for 185 us, the FFI library automatically performs the conversion when calling 186 the function (truncating the FP value towards zero, like in C). 187 </p> 188 <p style="font-size: 8pt;"> 189 Some readers will notice that <tt>Sleep()</tt> is part of 190 <tt>KERNEL32.DLL</tt> and is also a <tt>stdcall</tt> function. So how 191 can this possibly work? The FFI library provides the <tt>ffi.C</tt> 192 default C library namespace, which allows calling functions from 193 the default set of libraries, like a C compiler would. Also, the 194 FFI library automatically detects <tt>stdcall</tt> functions, so you 195 don't need to declare them as such. 196 </p> 197 <p> 198 <span class="mark">⑤</span> The <tt>poll()</tt> 199 function takes a couple more arguments we're not going to use. You can 200 simply use <tt>nil</tt> to pass a <tt>NULL</tt> pointer and <tt>0</tt> 201 for the <tt>nfds</tt> parameter. Please note that the 202 number <tt>0</tt> <em>does not convert to a pointer value</em>, 203 unlike in C++. You really have to pass pointers to pointer arguments 204 and numbers to number arguments. 205 </p> 206 <p style="font-size: 8pt;"> 207 The page on <a href="ext_ffi_semantics.html">FFI semantics</a> has all 208 of the gory details about 209 <a href="ext_ffi_semantics.html#convert">conversions between Lua 210 objects and C types</a>. For the most part you don't have to deal 211 with this, as it's performed automatically and it's carefully designed 212 to bridge the semantic differences between Lua and C. 213 </p> 214 <p> 215 <span class="mark">⑥</span> Now that we have defined 216 our own <tt>sleep()</tt> function, we can just call it from plain Lua 217 code. That wasn't so bad, huh? Turning these boring animated dots into 218 a fascinating best-selling game is left as an exercise for the reader. 219 :-) 220 </p> 221 222 <h2 id="zlib">Accessing the zlib Compression Library</h2> 223 <p> 224 The following code shows how to access the <a 225 href="http://zlib.net/">zlib</a> compression library from Lua code. 226 We'll define two convenience wrapper functions that take a string and 227 compress or uncompress it to another string: 228 </p> 229 <pre class="code mark"> 230 <span class="codemark"> 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 ⑦</span>local ffi = require("ffi") 258 ffi.cdef[[ 259 <span style="color:#00a000;">unsigned long compressBound(unsigned long sourceLen); 260 int compress2(uint8_t *dest, unsigned long *destLen, 261 const uint8_t *source, unsigned long sourceLen, int level); 262 int uncompress(uint8_t *dest, unsigned long *destLen, 263 const uint8_t *source, unsigned long sourceLen);</span> 264 ]] 265 local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z") 266 267 local function compress(txt) 268 local n = zlib.compressBound(#txt) 269 local buf = ffi.new("uint8_t[?]", n) 270 local buflen = ffi.new("unsigned long[1]", n) 271 local res = zlib.compress2(buf, buflen, txt, #txt, 9) 272 assert(res == 0) 273 return ffi.string(buf, buflen[0]) 274 end 275 276 local function uncompress(comp, n) 277 local buf = ffi.new("uint8_t[?]", n) 278 local buflen = ffi.new("unsigned long[1]", n) 279 local res = zlib.uncompress(buf, buflen, comp, #comp) 280 assert(res == 0) 281 return ffi.string(buf, buflen[0]) 282 end 283 284 -- Simple test code. 285 local txt = string.rep("abcd", 1000) 286 print("Uncompressed size: ", #txt) 287 local c = compress(txt) 288 print("Compressed size: ", #c) 289 local txt2 = uncompress(c, #txt) 290 assert(txt2 == txt) 291 </pre> 292 <p> 293 Here's the step-by-step explanation: 294 </p> 295 <p> 296 <span class="mark">①</span> This defines some of the 297 C functions provided by zlib. For the sake of this example, some 298 type indirections have been reduced and it uses the pre-defined 299 fixed-size integer types, while still adhering to the zlib API/ABI. 300 </p> 301 <p> 302 <span class="mark">②</span> This loads the zlib shared 303 library. On POSIX systems it's named <tt>libz.so</tt> and usually 304 comes pre-installed. Since <tt>ffi.load()</tt> automatically adds any 305 missing standard prefixes/suffixes, we can simply load the 306 <tt>"z"</tt> library. On Windows it's named <tt>zlib1.dll</tt> and 307 you'll have to download it first from the 308 <a href="http://zlib.net/"><span class="ext">»</span> zlib site</a>. The check for 309 <tt>ffi.os</tt> makes sure we pass the right name to 310 <tt>ffi.load()</tt>. 311 </p> 312 <p> 313 <span class="mark">③</span> First, the maximum size of 314 the compression buffer is obtained by calling the 315 <tt>zlib.compressBound</tt> function with the length of the 316 uncompressed string. The next line allocates a byte buffer of this 317 size. The <tt>[?]</tt> in the type specification indicates a 318 variable-length array (VLA). The actual number of elements of this 319 array is given as the 2nd argument to <tt>ffi.new()</tt>. 320 </p> 321 <p> 322 <span class="mark">④</span> This may look strange at 323 first, but have a look at the declaration of the <tt>compress2</tt> 324 function from zlib: the destination length is defined as a pointer! 325 This is because you pass in the maximum buffer size and get back the 326 actual length that was used. 327 </p> 328 <p> 329 In C you'd pass in the address of a local variable 330 (<tt>&buflen</tt>). But since there's no address-of operator in 331 Lua, we'll just pass in a one-element array. Conveniently it can be 332 initialized with the maximum buffer size in one step. Calling the 333 actual <tt>zlib.compress2</tt> function is then straightforward. 334 </p> 335 <p> 336 <span class="mark">⑤</span> We want to return the 337 compressed data as a Lua string, so we'll use <tt>ffi.string()</tt>. 338 It needs a pointer to the start of the data and the actual length. The 339 length has been returned in the <tt>buflen</tt> array, so we'll just 340 get it from there. 341 </p> 342 <p style="font-size: 8pt;"> 343 Note that since the function returns now, the <tt>buf</tt> and 344 <tt>buflen</tt> variables will eventually be garbage collected. This 345 is fine, because <tt>ffi.string()</tt> has copied the contents to a 346 newly created (interned) Lua string. If you plan to call this function 347 lots of times, consider reusing the buffers and/or handing back the 348 results in buffers instead of strings. This will reduce the overhead 349 for garbage collection and string interning. 350 </p> 351 <p> 352 <span class="mark">⑥</span> The <tt>uncompress</tt> 353 functions does the exact opposite of the <tt>compress</tt> function. 354 The compressed data doesn't include the size of the original string, 355 so this needs to be passed in. Otherwise no surprises here. 356 </p> 357 <p> 358 <span class="mark">⑦</span> The code, that makes use 359 of the functions we just defined, is just plain Lua code. It doesn't 360 need to know anything about the LuaJIT FFI — the convenience 361 wrapper functions completely hide it. 362 </p> 363 <p> 364 One major advantage of the LuaJIT FFI is that you are now able to 365 write those wrappers <em>in Lua</em>. And at a fraction of the time it 366 would cost you to create an extra C module using the Lua/C API. 367 Many of the simpler C functions can probably be used directly 368 from your Lua code, without any wrappers. 369 </p> 370 <p style="font-size: 8pt;"> 371 Side note: the zlib API uses the <tt>long</tt> type for passing 372 lengths and sizes around. But all those zlib functions actually only 373 deal with 32 bit values. This is an unfortunate choice for a 374 public API, but may be explained by zlib's history — we'll just 375 have to deal with it. 376 </p> 377 <p style="font-size: 8pt;"> 378 First, you should know that a <tt>long</tt> is a 64 bit type e.g. 379 on POSIX/x64 systems, but a 32 bit type on Windows/x64 and on 380 32 bit systems. Thus a <tt>long</tt> result can be either a plain 381 Lua number or a boxed 64 bit integer cdata object, depending on 382 the target system. 383 </p> 384 <p style="font-size: 8pt;"> 385 Ok, so the <tt>ffi.*</tt> functions generally accept cdata objects 386 wherever you'd want to use a number. That's why we get a away with 387 passing <tt>n</tt> to <tt>ffi.string()</tt> above. But other Lua 388 library functions or modules don't know how to deal with this. So for 389 maximum portability one needs to use <tt>tonumber()</tt> on returned 390 <tt>long</tt> results before passing them on. Otherwise the 391 application might work on some systems, but would fail in a POSIX/x64 392 environment. 393 </p> 394 395 <h2 id="metatype">Defining Metamethods for a C Type</h2> 396 <p> 397 The following code explains how to define metamethods for a C type. 398 We define a simple point type and add some operations to it: 399 </p> 400 <pre class="code mark"> 401 <span class="codemark"> 402 ① 403 404 405 406 ② 407 408 ③ 409 410 ④ 411 412 413 414 ⑤ 415 416 ⑥</span>local ffi = require("ffi") 417 ffi.cdef[[ 418 <span style="color:#00a000;">typedef struct { double x, y; } point_t;</span> 419 ]] 420 421 local point 422 local mt = { 423 __add = function(a, b) return point(a.x+b.x, a.y+b.y) end, 424 __len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end, 425 __index = { 426 area = function(a) return a.x*a.x + a.y*a.y end, 427 }, 428 } 429 point = ffi.metatype("point_t", mt) 430 431 local a = point(3, 4) 432 print(a.x, a.y) --> 3 4 433 print(#a) --> 5 434 print(a:area()) --> 25 435 local b = a + point(0.5, 8) 436 print(#b) --> 12.5 437 </pre> 438 <p> 439 Here's the step-by-step explanation: 440 </p> 441 <p> 442 <span class="mark">①</span> This defines the C type for a 443 two-dimensional point object. 444 </p> 445 <p> 446 <span class="mark">②</span> We have to declare the variable 447 holding the point constructor first, because it's used inside of a 448 metamethod. 449 </p> 450 <p> 451 <span class="mark">③</span> Let's define an <tt>__add</tt> 452 metamethod which adds the coordinates of two points and creates a new 453 point object. For simplicity, this function assumes that both arguments 454 are points. But it could be any mix of objects, if at least one operand 455 is of the required type (e.g. adding a point plus a number or vice 456 versa). Our <tt>__len</tt> metamethod returns the distance of a point to 457 the origin. 458 </p> 459 <p> 460 <span class="mark">④</span> If we run out of operators, we can 461 define named methods, too. Here the <tt>__index</tt> table defines an 462 <tt>area</tt> function. For custom indexing needs, one might want to 463 define <tt>__index</tt> and <tt>__newindex</tt> <em>functions</em> instead. 464 </p> 465 <p> 466 <span class="mark">⑤</span> This associates the metamethods with 467 our C type. This only needs to be done once. For convenience, a 468 constructor is returned by 469 <a href="ext_ffi_api.html#ffi_metatype"><tt>ffi.metatype()</tt></a>. 470 We're not required to use it, though. The original C type can still 471 be used e.g. to create an array of points. The metamethods automatically 472 apply to any and all uses of this type. 473 </p> 474 <p> 475 Please note that the association with a metatable is permanent and 476 <b>the metatable must not be modified afterwards!</b> Ditto for the 477 <tt>__index</tt> table. 478 </p> 479 <p> 480 <span class="mark">⑥</span> Here are some simple usage examples 481 for the point type and their expected results. The pre-defined 482 operations (such as <tt>a.x</tt>) can be freely mixed with the newly 483 defined metamethods. Note that <tt>area</tt> is a method and must be 484 called with the Lua syntax for methods: <tt>a:area()</tt>, not 485 <tt>a.area()</tt>. 486 </p> 487 <p> 488 The C type metamethod mechanism is most useful when used in 489 conjunction with C libraries that are written in an object-oriented 490 style. Creators return a pointer to a new instance and methods take an 491 instance pointer as the first argument. Sometimes you can just point 492 <tt>__index</tt> to the library namespace and <tt>__gc</tt> to the 493 destructor and you're done. But often enough you'll want to add 494 convenience wrappers, e.g. to return actual Lua strings or when 495 returning multiple values. 496 </p> 497 <p> 498 Some C libraries only declare instance pointers as an opaque 499 <tt>void *</tt> type. In this case you can use a fake type for all 500 declarations, e.g. a pointer to a named (incomplete) struct will do: 501 <tt>typedef struct foo_type *foo_handle</tt>. The C side doesn't 502 know what you declare with the LuaJIT FFI, but as long as the underlying 503 types are compatible, everything still works. 504 </p> 505 506 <h2 id="idioms">Translating C Idioms</h2> 507 <p> 508 Here's a list of common C idioms and their translation to the 509 LuaJIT FFI: 510 </p> 511 <table class="idiomtable"> 512 <tr class="idiomhead"> 513 <td class="idiomdesc">Idiom</td> 514 <td class="idiomc">C code</td> 515 <td class="idiomlua">Lua code</td> 516 </tr> 517 <tr class="odd separate"> 518 <td class="idiomdesc">Pointer dereference<br><tt>int *p;</tt></td><td class="idiomc"><tt>x = *p;<br>*p = y;</tt></td><td class="idiomlua"><tt>x = <b>p[0]</b><br><b>p[0]</b> = y</tt></td></tr> 519 <tr class="even"> 520 <td class="idiomdesc">Pointer indexing<br><tt>int i, *p;</tt></td><td class="idiomc"><tt>x = p[i];<br>p[i+1] = y;</tt></td><td class="idiomlua"><tt>x = p[i]<br>p[i+1] = y</tt></td></tr> 521 <tr class="odd"> 522 <td class="idiomdesc">Array indexing<br><tt>int i, a[];</tt></td><td class="idiomc"><tt>x = a[i];<br>a[i+1] = y;</tt></td><td class="idiomlua"><tt>x = a[i]<br>a[i+1] = y</tt></td></tr> 523 <tr class="even separate"> 524 <td class="idiomdesc"><tt>struct</tt>/<tt>union</tt> dereference<br><tt>struct foo s;</tt></td><td class="idiomc"><tt>x = s.field;<br>s.field = y;</tt></td><td class="idiomlua"><tt>x = s.field<br>s.field = y</tt></td></tr> 525 <tr class="odd"> 526 <td class="idiomdesc"><tt>struct</tt>/<tt>union</tt> pointer deref.<br><tt>struct foo *sp;</tt></td><td class="idiomc"><tt>x = sp->field;<br>sp->field = y;</tt></td><td class="idiomlua"><tt>x = <b>s.field</b><br><b>s.field</b> = y</tt></td></tr> 527 <tr class="even separate"> 528 <td class="idiomdesc">Pointer arithmetic<br><tt>int i, *p;</tt></td><td class="idiomc"><tt>x = p + i;<br>y = p - i;</tt></td><td class="idiomlua"><tt>x = p + i<br>y = p - i</tt></td></tr> 529 <tr class="odd"> 530 <td class="idiomdesc">Pointer difference<br><tt>int *p1, *p2;</tt></td><td class="idiomc"><tt>x = p1 - p2;</tt></td><td class="idiomlua"><tt>x = p1 - p2</tt></td></tr> 531 <tr class="even"> 532 <td class="idiomdesc">Array element pointer<br><tt>int i, a[];</tt></td><td class="idiomc"><tt>x = &a[i];</tt></td><td class="idiomlua"><tt>x = <b>a+i</b></tt></td></tr> 533 <tr class="odd"> 534 <td class="idiomdesc">Cast pointer to address<br><tt>int *p;</tt></td><td class="idiomc"><tt>x = (intptr_t)p;</tt></td><td class="idiomlua"><tt>x = <b>tonumber(<br> ffi.cast("intptr_t",<br> p))</b></tt></td></tr> 535 <tr class="even separate"> 536 <td class="idiomdesc">Functions with outargs<br><tt>void foo(int *inoutlen);</tt></td><td class="idiomc"><tt>int len = x;<br>foo(&len);<br>y = len;</tt></td><td class="idiomlua"><tt><b>local len =<br> ffi.new("int[1]", x)<br>foo(len)<br>y = len[0]</b></tt></td></tr> 537 <tr class="odd"> 538 <td class="idiomdesc"><a href="ext_ffi_semantics.html#convert_vararg">Vararg conversions</a><br><tt>int printf(char *fmt, ...);</tt></td><td class="idiomc"><tt>printf("%g", 1.0);<br>printf("%d", 1);<br> </tt></td><td class="idiomlua"><tt>printf("%g", 1);<br>printf("%d",<br> <b>ffi.new("int", 1)</b>)</tt></td></tr> 539 </table> 540 541 <h2 id="cache">To Cache or Not to Cache</h2> 542 <p> 543 It's a common Lua idiom to cache library functions in local variables 544 or upvalues, e.g.: 545 </p> 546 <pre class="code"> 547 local byte, char = string.byte, string.char 548 local function foo(x) 549 return char(byte(x)+1) 550 end 551 </pre> 552 <p> 553 This replaces several hash-table lookups with a (faster) direct use of 554 a local or an upvalue. This is less important with LuaJIT, since the 555 JIT compiler optimizes hash-table lookups a lot and is even able to 556 hoist most of them out of the inner loops. It can't eliminate 557 <em>all</em> of them, though, and it saves some typing for often-used 558 functions. So there's still a place for this, even with LuaJIT. 559 </p> 560 <p> 561 The situation is a bit different with C function calls via the 562 FFI library. The JIT compiler has special logic to eliminate <em>all 563 of the lookup overhead</em> for functions resolved from a 564 <a href="ext_ffi_semantics.html#clib">C library namespace</a>! 565 Thus it's not helpful and actually counter-productive to cache 566 individual C functions like this: 567 </p> 568 <pre class="code"> 569 local <b>funca</b>, <b>funcb</b> = ffi.C.funca, ffi.C.funcb -- <span style="color:#c00000;">Not helpful!</span> 570 local function foo(x, n) 571 for i=1,n do <b>funcb</b>(<b>funca</b>(x, i), 1) end 572 end 573 </pre> 574 <p> 575 This turns them into indirect calls and generates bigger and slower 576 machine code. Instead you'll want to cache the namespace itself and 577 rely on the JIT compiler to eliminate the lookups: 578 </p> 579 <pre class="code"> 580 local <b>C</b> = ffi.C -- <span style="color:#00a000;">Instead use this!</span> 581 local function foo(x, n) 582 for i=1,n do <b>C.funcb</b>(<b>C.funca</b>(x, i), 1) end 583 end 584 </pre> 585 <p> 586 This generates both shorter and faster code. So <b>don't cache 587 C functions</b>, but <b>do</b> cache namespaces! Most often the 588 namespace is already in a local variable at an outer scope, e.g. from 589 <tt>local lib = ffi.load(...)</tt>. Note that copying 590 it to a local variable in the function scope is unnecessary. 591 </p> 592 <br class="flush"> 593 </div> 594 <div id="foot"> 595 <hr class="hide"> 596 Copyright © 2005-2016 Mike Pall 597 <span class="noprint"> 598 · 599 <a href="contact.html">Contact</a> 600 </span> 601 </div> 602 </body> 603 </html>