ext_ffi.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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 Library</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-2012, 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. span.codemark { position:absolute; left: 16em; color: #4040c0; }
  13. span.mark { color: #4040c0; font-family: Courier New, Courier, monospace;
  14. line-height: 1.1; }
  15. pre.mark { padding-left: 2em; }
  16. </style>
  17. </head>
  18. <body>
  19. <div id="site">
  20. <a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
  21. </div>
  22. <div id="head">
  23. <h1>FFI Library</h1>
  24. </div>
  25. <div id="nav">
  26. <ul><li>
  27. <a href="luajit.html">LuaJIT</a>
  28. <ul><li>
  29. <a href="install.html">Installation</a>
  30. </li><li>
  31. <a href="running.html">Running</a>
  32. </li></ul>
  33. </li><li>
  34. <a href="extensions.html">Extensions</a>
  35. <ul><li>
  36. <a class="current" href="ext_ffi.html">FFI Library</a>
  37. <ul><li>
  38. <a href="ext_ffi_tutorial.html">FFI Tutorial</a>
  39. </li><li>
  40. <a href="ext_ffi_api.html">ffi.* API</a>
  41. </li><li>
  42. <a href="ext_ffi_semantics.html">FFI Semantics</a>
  43. </li></ul>
  44. </li><li>
  45. <a href="ext_jit.html">jit.* Library</a>
  46. </li><li>
  47. <a href="ext_c_api.html">Lua/C API</a>
  48. </li></ul>
  49. </li><li>
  50. <a href="status.html">Status</a>
  51. <ul><li>
  52. <a href="changes.html">Changes</a>
  53. </li></ul>
  54. </li><li>
  55. <a href="faq.html">FAQ</a>
  56. </li><li>
  57. <a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
  58. </li><li>
  59. <a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
  60. </li><li>
  61. <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
  62. </li><li>
  63. <a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
  64. </li></ul>
  65. </div>
  66. <div id="main">
  67. <p>
  68. The FFI library allows <b>calling external C&nbsp;functions</b> and
  69. <b>using C&nbsp;data structures</b> from pure Lua code.
  70. </p>
  71. <p>
  72. The FFI library largely obviates the need to write tedious manual
  73. Lua/C bindings in C. No need to learn a separate binding language
  74. &mdash; <b>it parses plain C&nbsp;declarations!</b> These can be
  75. cut-n-pasted from C&nbsp;header files or reference manuals. It's up to
  76. the task of binding large libraries without the need for dealing with
  77. fragile binding generators.
  78. </p>
  79. <p>
  80. The FFI library is tightly integrated into LuaJIT (it's not available
  81. as a separate module). The code generated by the JIT-compiler for
  82. accesses to C&nbsp;data structures from Lua code is on par with the
  83. code a C&nbsp;compiler would generate. Calls to C&nbsp;functions can
  84. be inlined in JIT-compiled code, unlike calls to functions bound via
  85. the classic Lua/C API.
  86. </p>
  87. <p>
  88. This page gives a short introduction to the usage of the FFI library.
  89. <em>Please use the FFI sub-topics in the navigation bar to learn more.</em>
  90. </p>
  91. <h2 id="call">Motivating Example: Calling External C Functions</h2>
  92. <p>
  93. It's really easy to call an external C&nbsp;library function:
  94. </p>
  95. <pre class="code mark">
  96. <span class="codemark">&#9312;
  97. &#9313;
  98. &#9314;</span>local ffi = require("ffi")
  99. ffi.cdef[[
  100. <span style="color:#00a000;">int printf(const char *fmt, ...);</span>
  101. ]]
  102. ffi.C.printf("Hello %s!", "world")
  103. </pre>
  104. <p>
  105. So, let's pick that apart:
  106. </p>
  107. <p>
  108. <span class="mark">&#9312;</span> Load the FFI library.
  109. </p>
  110. <p>
  111. <span class="mark">&#9313;</span> Add a C&nbsp;declaration
  112. for the function. The part inside the double-brackets (in green) is
  113. just standard C&nbsp;syntax.
  114. </p>
  115. <p>
  116. <span class="mark">&#9314;</span> Call the named
  117. C&nbsp;function &mdash; Yes, it's that simple!
  118. </p>
  119. <p style="font-size: 8pt;">
  120. Actually, what goes on behind the scenes is far from simple: <span
  121. style="color:#4040c0;">&#9314;</span> makes use of the standard
  122. C&nbsp;library namespace <tt>ffi.C</tt>. Indexing this namespace with
  123. a symbol name (<tt>"printf"</tt>) automatically binds it to the
  124. standard C&nbsp;library. The result is a special kind of object which,
  125. when called, runs the <tt>printf</tt> function. The arguments passed
  126. to this function are automatically converted from Lua objects to the
  127. corresponding C&nbsp;types.
  128. </p>
  129. <p>
  130. Ok, so maybe the use of <tt>printf()</tt> wasn't such a spectacular
  131. example. You could have done that with <tt>io.write()</tt> and
  132. <tt>string.format()</tt>, too. But you get the idea ...
  133. </p>
  134. <p>
  135. So here's something to pop up a message box on Windows:
  136. </p>
  137. <pre class="code">
  138. local ffi = require("ffi")
  139. ffi.cdef[[
  140. <span style="color:#00a000;">int MessageBoxA(void *w, const char *txt, const char *cap, int type);</span>
  141. ]]
  142. ffi.C.MessageBoxA(nil, "Hello world!", "Test", 0)
  143. </pre>
  144. <p>
  145. Bing! Again, that was far too easy, no?
  146. </p>
  147. <p style="font-size: 8pt;">
  148. Compare this with the effort required to bind that function using the
  149. classic Lua/C API: create an extra C&nbsp;file, add a C&nbsp;function
  150. that retrieves and checks the argument types passed from Lua and calls
  151. the actual C&nbsp;function, add a list of module functions and their
  152. names, add a <tt>luaopen_*</tt> function and register all module
  153. functions, compile and link it into a shared library (DLL), move it to
  154. the proper path, add Lua code that loads the module aaaand ... finally
  155. call the binding function. Phew!
  156. </p>
  157. <h2 id="cdata">Motivating Example: Using C Data Structures</h2>
  158. <p>
  159. The FFI library allows you to create and access C&nbsp;data
  160. structures. Of course the main use for this is for interfacing with
  161. C&nbsp;functions. But they can be used stand-alone, too.
  162. </p>
  163. <p>
  164. Lua is built upon high-level data types. They are flexible, extensible
  165. and dynamic. That's why we all love Lua so much. Alas, this can be
  166. inefficient for certain tasks, where you'd really want a low-level
  167. data type. E.g. a large array of a fixed structure needs to be
  168. implemented with a big table holding lots of tiny tables. This imposes
  169. both a substantial memory overhead as well as a performance overhead.
  170. </p>
  171. <p>
  172. Here's a sketch of a library that operates on color images plus a
  173. simple benchmark. First, the plain Lua version:
  174. </p>
  175. <pre class="code">
  176. local floor = math.floor
  177. local function image_ramp_green(n)
  178. local img = {}
  179. local f = 255/(n-1)
  180. for i=1,n do
  181. img[i] = { red = 0, green = floor((i-1)*f), blue = 0, alpha = 255 }
  182. end
  183. return img
  184. end
  185. local function image_to_grey(img, n)
  186. for i=1,n do
  187. local y = floor(0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue)
  188. img[i].red = y; img[i].green = y; img[i].blue = y
  189. end
  190. end
  191. local N = 400*400
  192. local img = image_ramp_green(N)
  193. for i=1,1000 do
  194. image_to_grey(img, N)
  195. end
  196. </pre>
  197. <p>
  198. This creates a table with 160.000 pixels, each of which is a table
  199. holding four number values in the range of 0-255. First an image with
  200. a green ramp is created (1D for simplicity), then the image is
  201. converted to greyscale 1000 times. Yes, that's silly, but I was in
  202. need of a simple example ...
  203. </p>
  204. <p>
  205. And here's the FFI version. The modified parts have been marked in
  206. bold:
  207. </p>
  208. <pre class="code mark">
  209. <span class="codemark">&#9312;
  210. &#9313;
  211. &#9314;
  212. &#9315;
  213. &#9314;
  214. &#9316;</span><b>local ffi = require("ffi")
  215. ffi.cdef[[
  216. </b><span style="color:#00a000;">typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel;</span><b>
  217. ]]</b>
  218. local function image_ramp_green(n)
  219. <b>local img = ffi.new("rgba_pixel[?]", n)</b>
  220. local f = 255/(n-1)
  221. for i=<b>0,n-1</b> do
  222. <b>img[i].green = i*f</b>
  223. <b>img[i].alpha = 255</b>
  224. end
  225. return img
  226. end
  227. local function image_to_grey(img, n)
  228. for i=<b>0,n-1</b> do
  229. local y = <b>0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue</b>
  230. img[i].red = y; img[i].green = y; img[i].blue = y
  231. end
  232. end
  233. local N = 400*400
  234. local img = image_ramp_green(N)
  235. for i=1,1000 do
  236. image_to_grey(img, N)
  237. end
  238. </pre>
  239. <p>
  240. Ok, so that wasn't too difficult:
  241. </p>
  242. <p>
  243. <span class="mark">&#9312;</span> First, load the FFI
  244. library and declare the low-level data type. Here we choose a
  245. <tt>struct</tt> which holds four byte fields, one for each component
  246. of a 4x8&nbsp;bit RGBA pixel.
  247. </p>
  248. <p>
  249. <span class="mark">&#9313;</span> Creating the data
  250. structure with <tt>ffi.new()</tt> is straightforward &mdash; the
  251. <tt>'?'</tt> is a placeholder for the number of elements of a
  252. variable-length array.
  253. </p>
  254. <p>
  255. <span class="mark">&#9314;</span> C&nbsp;arrays are
  256. zero-based, so the indexes have to run from <tt>0</tt> to
  257. <tt>n-1</tt>. One might want to allocate one more element instead to
  258. simplify converting legacy code.
  259. </p>
  260. <p>
  261. <span class="mark">&#9315;</span> Since <tt>ffi.new()</tt>
  262. zero-fills the array by default, we only need to set the green and the
  263. alpha fields.
  264. </p>
  265. <p>
  266. <span class="mark">&#9316;</span> The calls to
  267. <tt>math.floor()</tt> can be omitted here, because floating-point
  268. numbers are already truncated towards zero when converting them to an
  269. integer. This happens implicitly when the number is stored in the
  270. fields of each pixel.
  271. </p>
  272. <p>
  273. Now let's have a look at the impact of the changes: first, memory
  274. consumption for the image is down from 22&nbsp;Megabytes to
  275. 640&nbsp;Kilobytes (400*400*4 bytes). That's a factor of 35x less! So,
  276. yes, tables do have a noticeable overhead. BTW: The original program
  277. would consume 40&nbsp;Megabytes in plain Lua (on x64).
  278. </p>
  279. <p>
  280. Next, performance: the pure Lua version runs in 9.57 seconds (52.9
  281. seconds with the Lua interpreter) and the FFI version runs in 0.48
  282. seconds on my machine (YMMV). That's a factor of 20x faster (110x
  283. faster than the Lua interpreter).
  284. </p>
  285. <p style="font-size: 8pt;">
  286. The avid reader may notice that converting the pure Lua version over
  287. to use array indexes for the colors (<tt>[1]</tt> instead of
  288. <tt>.red</tt>, <tt>[2]</tt> instead of <tt>.green</tt> etc.) ought to
  289. be more compact and faster. This is certainly true (by a factor of
  290. ~1.7x). Switching to a struct-of-arrays would help, too.
  291. </p>
  292. <p style="font-size: 8pt;">
  293. However the resulting code would be less idiomatic and rather
  294. error-prone. And it still doesn't get even close to the performance of
  295. the FFI version of the code. Also, high-level data structures cannot
  296. be easily passed to other C&nbsp;functions, especially I/O functions,
  297. without undue conversion penalties.
  298. </p>
  299. <br class="flush">
  300. </div>
  301. <div id="foot">
  302. <hr class="hide">
  303. Copyright &copy; 2005-2012 Mike Pall
  304. <span class="noprint">
  305. &middot;
  306. <a href="contact.html">Contact</a>
  307. </span>
  308. </div>
  309. </body>
  310. </html>