diff options
author | Mike Pall <mike> | 2011-02-11 13:50:01 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-02-11 14:51:20 +0100 |
commit | 1f0006ac71fd4eb308ab900b0b9917e1dd046680 (patch) | |
tree | 93a6e6435ef45c776c28da2d3f4c8330e0e72968 /doc/ext_ffi.html | |
parent | a5aade2fa9ff89f9f3c4a91261071299de0d0fa4 (diff) | |
download | luajit-1f0006ac71fd4eb308ab900b0b9917e1dd046680.tar.gz luajit-1f0006ac71fd4eb308ab900b0b9917e1dd046680.tar.bz2 luajit-1f0006ac71fd4eb308ab900b0b9917e1dd046680.zip |
Cleanup of docs.
Diffstat (limited to 'doc/ext_ffi.html')
-rw-r--r-- | doc/ext_ffi.html | 79 |
1 files changed, 55 insertions, 24 deletions
diff --git a/doc/ext_ffi.html b/doc/ext_ffi.html index 1fd276dc..0bbf7606 100644 --- a/doc/ext_ffi.html +++ b/doc/ext_ffi.html | |||
@@ -8,6 +8,12 @@ | |||
8 | <meta name="Language" content="en"> | 8 | <meta name="Language" content="en"> |
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | 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"> | 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> | ||
11 | </head> | 17 | </head> |
12 | <body> | 18 | <body> |
13 | <div id="site"> | 19 | <div id="site"> |
@@ -55,16 +61,20 @@ | |||
55 | </div> | 61 | </div> |
56 | <div id="main"> | 62 | <div id="main"> |
57 | <p> | 63 | <p> |
58 | The FFI library allows calling external C functions and the use | 64 | |
59 | of C data structures from pure Lua code. | 65 | The FFI library allows <b>calling external C functions</b> and |
66 | <b>using C data structures</b> from pure Lua code. | ||
67 | |||
60 | </p> | 68 | </p> |
61 | <p> | 69 | <p> |
70 | |||
62 | The FFI library largely obviates the need to write tedious manual | 71 | The FFI library largely obviates the need to write tedious manual |
63 | Lua/C bindings in C. It doesn't require learning a separate binding | 72 | Lua/C bindings in C. No need to learn a separate binding language |
64 | language — it parses plain C declarations, which can be | 73 | — <b>it parses plain C declarations!</b> These can be |
65 | cut-n-pasted from C header files or reference manuals. It's up to | 74 | cut-n-pasted from C header files or reference manuals. It's up to |
66 | the task of binding large libraries without the need for dealing with | 75 | the task of binding large libraries without the need for dealing with |
67 | fragile binding generators. | 76 | fragile binding generators. |
77 | |||
68 | </p> | 78 | </p> |
69 | <p> | 79 | <p> |
70 | The FFI library is tightly integrated into LuaJIT (it's not available | 80 | The FFI library is tightly integrated into LuaJIT (it's not available |
@@ -83,26 +93,30 @@ Please use the FFI sub-topics in the navigation bar to learn more. | |||
83 | <p> | 93 | <p> |
84 | It's really easy to call an external C library function: | 94 | It's really easy to call an external C library function: |
85 | </p> | 95 | </p> |
86 | <pre class="code"> | 96 | <pre class="code mark"> |
87 | local ffi = require("ffi") <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">①</span> | 97 | <span class="codemark">① |
88 | ffi.cdef[[ <span style="color:#f0f4ff;">//</span><span style="color:#4040c0;">②</span> | 98 | ② |
99 | |||
100 | |||
101 | ③</span>local ffi = require("ffi") | ||
102 | ffi.cdef[[ | ||
89 | <span style="color:#00a000;">int printf(const char *fmt, ...);</span> | 103 | <span style="color:#00a000;">int printf(const char *fmt, ...);</span> |
90 | ]] | 104 | ]] |
91 | ffi.C.printf("Hello %s!", "world") <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">③</span> | 105 | ffi.C.printf("Hello %s!", "world") |
92 | </pre> | 106 | </pre> |
93 | <p> | 107 | <p> |
94 | So, let's pick that apart: | 108 | So, let's pick that apart: |
95 | </p> | 109 | </p> |
96 | <p> | 110 | <p> |
97 | <span style="color:#4040c0;">①</span> Load the FFI library. | 111 | <span class="mark">①</span> Load the FFI library. |
98 | </p> | 112 | </p> |
99 | <p> | 113 | <p> |
100 | <span style="color:#4040c0;">②</span> Add a C declaration | 114 | <span class="mark">②</span> Add a C declaration |
101 | for the function. The part inside the double-brackets (in green) is | 115 | for the function. The part inside the double-brackets (in green) is |
102 | just standard C syntax. | 116 | just standard C syntax. |
103 | </p> | 117 | </p> |
104 | <p> | 118 | <p> |
105 | <span style="color:#4040c0;">③</span> Call the named | 119 | <span class="mark">③</span> Call the named |
106 | C function — Yes, it's that simple! | 120 | C function — Yes, it's that simple! |
107 | </p> | 121 | </p> |
108 | <p style="font-size: 8pt;"> | 122 | <p style="font-size: 8pt;"> |
@@ -198,25 +212,42 @@ need of a simple example ... | |||
198 | And here's the FFI version. The modified parts have been marked in | 212 | And here's the FFI version. The modified parts have been marked in |
199 | bold: | 213 | bold: |
200 | </p> | 214 | </p> |
201 | <pre class="code"> | 215 | <pre class="code mark"> |
202 | <b>local ffi = require("ffi")</b> <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">①</span> | 216 | <span class="codemark">① |
203 | <b>ffi.cdef[[ | 217 | |
218 | |||
219 | |||
220 | |||
221 | |||
222 | ② | ||
223 | |||
224 | ③ | ||
225 | ④ | ||
226 | |||
227 | |||
228 | |||
229 | |||
230 | |||
231 | |||
232 | ③ | ||
233 | ⑤</span><b>local ffi = require("ffi") | ||
234 | ffi.cdef[[ | ||
204 | </b><span style="color:#00a000;">typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel;</span><b> | 235 | </b><span style="color:#00a000;">typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel;</span><b> |
205 | ]]</b> | 236 | ]]</b> |
206 | 237 | ||
207 | local function image_ramp_green(n) | 238 | local function image_ramp_green(n) |
208 | <b>local img = ffi.new("rgba_pixel[?]", n)</b> <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">②</span> | 239 | <b>local img = ffi.new("rgba_pixel[?]", n)</b> |
209 | local f = 255/(n-1) | 240 | local f = 255/(n-1) |
210 | for i=<b>0,n-1</b> do <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">③</span> | 241 | for i=<b>0,n-1</b> do |
211 | <b>img[i].green = i*f</b> <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">④</span> | 242 | <b>img[i].green = i*f</b> |
212 | <b>img[i].alpha = 255</b> | 243 | <b>img[i].alpha = 255</b> |
213 | end | 244 | end |
214 | return img | 245 | return img |
215 | end | 246 | end |
216 | 247 | ||
217 | local function image_to_grey(img, n) | 248 | local function image_to_grey(img, n) |
218 | for i=<b>0,n-1</b> do <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">③</span> | 249 | for i=<b>0,n-1</b> do |
219 | local y = <b>0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue</b> <span style="color:#f0f4ff;">--</span><span style="color:#4040c0;">⑤</span> | 250 | local y = <b>0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue</b> |
220 | img[i].red = y; img[i].green = y; img[i].blue = y | 251 | img[i].red = y; img[i].green = y; img[i].blue = y |
221 | end | 252 | end |
222 | end | 253 | end |
@@ -231,30 +262,30 @@ end | |||
231 | Ok, so that wasn't too difficult: | 262 | Ok, so that wasn't too difficult: |
232 | </p> | 263 | </p> |
233 | <p> | 264 | <p> |
234 | <span style="color:#4040c0;">①</span> First, load the FFI | 265 | <span class="mark">①</span> First, load the FFI |
235 | library and declare the low-level data type. Here we choose a | 266 | library and declare the low-level data type. Here we choose a |
236 | <tt>struct</tt> which holds four byte fields, one for each component | 267 | <tt>struct</tt> which holds four byte fields, one for each component |
237 | of a 4x8 bit RGBA pixel. | 268 | of a 4x8 bit RGBA pixel. |
238 | </p> | 269 | </p> |
239 | <p> | 270 | <p> |
240 | <span style="color:#4040c0;">②</span> Creating the data | 271 | <span class="mark">②</span> Creating the data |
241 | structure with <tt>ffi.new()</tt> is straightforward — the | 272 | structure with <tt>ffi.new()</tt> is straightforward — the |
242 | <tt>'?'</tt> is a placeholder for the number of elements of a | 273 | <tt>'?'</tt> is a placeholder for the number of elements of a |
243 | variable-length array. | 274 | variable-length array. |
244 | </p> | 275 | </p> |
245 | <p> | 276 | <p> |
246 | <span style="color:#4040c0;">③</span> C arrays are | 277 | <span class="mark">③</span> C arrays are |
247 | zero-based, so the indexes have to run from <tt>0</tt> to | 278 | zero-based, so the indexes have to run from <tt>0</tt> to |
248 | <tt>n-1</tt>. One might want to allocate one more element instead to | 279 | <tt>n-1</tt>. One might want to allocate one more element instead to |
249 | simplify converting legacy code. | 280 | simplify converting legacy code. |
250 | </p> | 281 | </p> |
251 | <p> | 282 | <p> |
252 | <span style="color:#4040c0;">④</span> Since <tt>ffi.new()</tt> | 283 | <span class="mark">④</span> Since <tt>ffi.new()</tt> |
253 | zero-fills the array by default, we only need to set the green and the | 284 | zero-fills the array by default, we only need to set the green and the |
254 | alpha fields. | 285 | alpha fields. |
255 | </p> | 286 | </p> |
256 | <p> | 287 | <p> |
257 | <span style="color:#4040c0;">⑤</span> The calls to | 288 | <span class="mark">⑤</span> The calls to |
258 | <tt>math.floor()</tt> can be omitted here, because floating-point | 289 | <tt>math.floor()</tt> can be omitted here, because floating-point |
259 | numbers are already truncated towards zero when converting them to an | 290 | numbers are already truncated towards zero when converting them to an |
260 | integer. This happens implicitly when the number is stored in the | 291 | integer. This happens implicitly when the number is stored in the |