From 3b6f37dd2c336987251d53a4678396ef38921b3e Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Tue, 12 Apr 2011 19:15:00 +0200 Subject: FFI: Add ctype metamethods and ffi.metatype(). --- doc/ext_ffi_tutorial.html | 93 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) (limited to 'doc/ext_ffi_tutorial.html') diff --git a/doc/ext_ffi_tutorial.html b/doc/ext_ffi_tutorial.html index 38126865..d5b04bc6 100644 --- a/doc/ext_ffi_tutorial.html +++ b/doc/ext_ffi_tutorial.html @@ -386,6 +386,99 @@ application might work on some systems, but would fail in a POSIX/x64 environment.

+

Defining Metamethods for a C Type

+

+The following code explains how to define metamethods for a C type. +We define a simple point type and add some operations to it: +

+
+ 
+①
+
+
+
+②
+
+③
+
+④
+
+
+
+⑤
+
+⑥local ffi = require("ffi")
+ffi.cdef[[
+typedef struct { double x, y; } point_t;
+]]
+
+local point
+local mt = {
+  __add = function(a, b) return point(a.x+b.x, a.y+b.y) end,
+  __len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end,
+  __index = {
+    area = function(a) return a.x*a.x + a.y*a.y end,
+  },
+}
+point = ffi.metatype("point_t", mt)
+
+local a = point(3, 4)
+print(a.x, a.y)  --> 3  4
+print(#a)        --> 5
+print(a:area())  --> 25
+local b = a + point(0.5, 8)
+print(#b)        --> 12.5
+
+

+Here's the step-by-step explanation: +

+

+ This defines the C type for a +two-dimensional point object. +

+

+ We have to declare the variable +holding the point constructor first, because it's used inside of a +metamethod. +

+

+ Let's define an __add +metamethod which adds the coordinates of two points and creates a new +point object. For simplicity, this function assumes that both arguments +are points. But it could be any mix of objects, if at least one operand +is of the required type (e.g. adding a point plus a number or vice +versa). Our __len metamethod returns the distance of a point to +the origin. +

+

+ If we run out of operators, we can +define named methods, too. Here the __index table defines an +area function. For custom indexing needs, one might want to +define __index and __newindex functions instead. +

+

+ This associates the metamethods with +our C type. This only needs to be done once. For convenience, a +constructor is returned by +ffi.metatype(). +We're not required to use it, though. The original C type can still +be used e.g. to create an array of points. The metamethods automatically +apply to any and all uses of this type. +

+

+Please note that the association with a metatable is permanent and +the metatable must not be modified afterwards! Ditto for the +__index table. +

+

+ Here are some simple usage examples +for the point type and their expected results. The pre-defined +operations (such as a.x) can be freely mixed with the newly +defined metamethods. Note that area is a method and must be +called with the Lua syntax for methods: a:area(), not +a.area(). +

+

Translating C Idioms

Here's a list of common C idioms and their translation to the -- cgit v1.2.3-55-g6feb