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 |
