From 1f0006ac71fd4eb308ab900b0b9917e1dd046680 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Fri, 11 Feb 2011 13:50:01 +0100 Subject: Cleanup of docs. --- doc/ext_ffi.html | 79 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 24 deletions(-) (limited to 'doc/ext_ffi.html') 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 @@ +
@@ -55,16 +61,20 @@

-The FFI library allows calling external C functions and the use -of C data structures from pure Lua code. + +The FFI library allows calling external C functions and +using C data structures from pure Lua code. +

+ The FFI library largely obviates the need to write tedious manual -Lua/C bindings in C. It doesn't require learning a separate binding -language — it parses plain C declarations, which can be +Lua/C bindings in C. No need to learn a separate binding language +— it parses plain C declarations! These can be cut-n-pasted from C header files or reference manuals. It's up to the task of binding large libraries without the need for dealing with fragile binding generators. +

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.

It's really easy to call an external C library function:

-
-local ffi = require("ffi") --
-ffi.cdef[[ //
+
+①
+②
+
+
+③local ffi = require("ffi")
+ffi.cdef[[
 int printf(const char *fmt, ...);
 ]]
-ffi.C.printf("Hello %s!", "world") --
+ffi.C.printf("Hello %s!", "world")
 

So, let's pick that apart:

- Load the FFI library. + Load the FFI library.

- Add a C declaration + Add a C declaration for the function. The part inside the double-brackets (in green) is just standard C syntax.

- Call the named + Call the named C function — Yes, it's that simple!

@@ -198,25 +212,42 @@ need of a simple example ... And here's the FFI version. The modified parts have been marked in bold:

-
-local ffi = require("ffi") --
-ffi.cdef[[
+
+①
+
+
+
+
+
+②
+
+③
+④
+
+
+
+
+
+
+③
+⑤local ffi = require("ffi")
+ffi.cdef[[
 typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel;
 ]]
 
 local function image_ramp_green(n)
-  local img = ffi.new("rgba_pixel[?]", n) --
+  local img = ffi.new("rgba_pixel[?]", n)
   local f = 255/(n-1)
-  for i=0,n-1 do --
-    img[i].green = i*f --
+  for i=0,n-1 do
+    img[i].green = i*f
     img[i].alpha = 255
   end
   return img
 end
 
 local function image_to_grey(img, n)
-  for i=0,n-1 do --
-    local y = 0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue --
+  for i=0,n-1 do
+    local y = 0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue
     img[i].red = y; img[i].green = y; img[i].blue = y
   end
 end
@@ -231,30 +262,30 @@ end
 Ok, so that wasn't too difficult:
 

- First, load the FFI + First, load the FFI library and declare the low-level data type. Here we choose a struct which holds four byte fields, one for each component of a 4x8 bit RGBA pixel.

- Creating the data + Creating the data structure with ffi.new() is straightforward — the '?' is a placeholder for the number of elements of a variable-length array.

- C arrays are + C arrays are zero-based, so the indexes have to run from 0 to n-1. One might want to allocate one more element instead to simplify converting legacy code.

- Since ffi.new() + Since ffi.new() zero-fills the array by default, we only need to set the green and the alpha fields.

- The calls to + The calls to math.floor() can be omitted here, because floating-point numbers are already truncated towards zero when converting them to an integer. This happens implicitly when the number is stored in the -- cgit v1.2.3-55-g6feb