diff options
author | Mike Pall <mike> | 2011-04-12 19:15:00 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2011-04-12 19:16:39 +0200 |
commit | 3b6f37dd2c336987251d53a4678396ef38921b3e (patch) | |
tree | 6e6176c37b600e461d078dbe663008dcc84d2418 /doc/ext_ffi_tutorial.html | |
parent | fa5cd010e8e28c7fe2338d0fdd538e95ddd88bcc (diff) | |
download | luajit-3b6f37dd2c336987251d53a4678396ef38921b3e.tar.gz luajit-3b6f37dd2c336987251d53a4678396ef38921b3e.tar.bz2 luajit-3b6f37dd2c336987251d53a4678396ef38921b3e.zip |
FFI: Add ctype metamethods and ffi.metatype().
Diffstat (limited to 'doc/ext_ffi_tutorial.html')
-rw-r--r-- | doc/ext_ffi_tutorial.html | 93 |
1 files changed, 93 insertions, 0 deletions
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 | |||
386 | environment. | 386 | environment. |
387 | </p> | 387 | </p> |
388 | 388 | ||
389 | <h2 id="metatype">Defining Metamethods for a C Type</h2> | ||
390 | <p> | ||
391 | The following code explains how to define metamethods for a C type. | ||
392 | We define a simple point type and add some operations to it: | ||
393 | </p> | ||
394 | <pre class="code mark"> | ||
395 | <span class="codemark"> | ||
396 | ① | ||
397 | |||
398 | |||
399 | |||
400 | ② | ||
401 | |||
402 | ③ | ||
403 | |||
404 | ④ | ||
405 | |||
406 | |||
407 | |||
408 | ⑤ | ||
409 | |||
410 | ⑥</span>local ffi = require("ffi") | ||
411 | ffi.cdef[[ | ||
412 | <span style="color:#00a000;">typedef struct { double x, y; } point_t;</span> | ||
413 | ]] | ||
414 | |||
415 | local point | ||
416 | local mt = { | ||
417 | __add = function(a, b) return point(a.x+b.x, a.y+b.y) end, | ||
418 | __len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end, | ||
419 | __index = { | ||
420 | area = function(a) return a.x*a.x + a.y*a.y end, | ||
421 | }, | ||
422 | } | ||
423 | point = ffi.metatype("point_t", mt) | ||
424 | |||
425 | local a = point(3, 4) | ||
426 | print(a.x, a.y) --> 3 4 | ||
427 | print(#a) --> 5 | ||
428 | print(a:area()) --> 25 | ||
429 | local b = a + point(0.5, 8) | ||
430 | print(#b) --> 12.5 | ||
431 | </pre> | ||
432 | <p> | ||
433 | Here's the step-by-step explanation: | ||
434 | </p> | ||
435 | <p> | ||
436 | <span class="mark">①</span> This defines the C type for a | ||
437 | two-dimensional point object. | ||
438 | </p> | ||
439 | <p> | ||
440 | <span class="mark">②</span> We have to declare the variable | ||
441 | holding the point constructor first, because it's used inside of a | ||
442 | metamethod. | ||
443 | </p> | ||
444 | <p> | ||
445 | <span class="mark">③</span> Let's define an <tt>__add</tt> | ||
446 | metamethod which adds the coordinates of two points and creates a new | ||
447 | point object. For simplicity, this function assumes that both arguments | ||
448 | are points. But it could be any mix of objects, if at least one operand | ||
449 | is of the required type (e.g. adding a point plus a number or vice | ||
450 | versa). Our <tt>__len</tt> metamethod returns the distance of a point to | ||
451 | the origin. | ||
452 | </p> | ||
453 | <p> | ||
454 | <span class="mark">④</span> If we run out of operators, we can | ||
455 | define named methods, too. Here the <tt>__index</tt> table defines an | ||
456 | <tt>area</tt> function. For custom indexing needs, one might want to | ||
457 | define <tt>__index</tt> and <tt>__newindex</tt> functions instead. | ||
458 | </p> | ||
459 | <p> | ||
460 | <span class="mark">⑤</span> This associates the metamethods with | ||
461 | our C type. This only needs to be done once. For convenience, a | ||
462 | constructor is returned by | ||
463 | <a href="ffi_ext_api.html#ffi_metatype"><tt>ffi.metatype()</tt></a>. | ||
464 | We're not required to use it, though. The original C type can still | ||
465 | be used e.g. to create an array of points. The metamethods automatically | ||
466 | apply to any and all uses of this type. | ||
467 | </p> | ||
468 | <p> | ||
469 | Please note that the association with a metatable is permanent and | ||
470 | <b>the metatable must not be modified afterwards!</b> Ditto for the | ||
471 | <tt>__index</tt> table. | ||
472 | </p> | ||
473 | <p> | ||
474 | <span class="mark">⑥</span> Here are some simple usage examples | ||
475 | for the point type and their expected results. The pre-defined | ||
476 | operations (such as <tt>a.x</tt>) can be freely mixed with the newly | ||
477 | defined metamethods. Note that <tt>area</tt> is a method and must be | ||
478 | called with the Lua syntax for methods: <tt>a:area()</tt>, not | ||
479 | <tt>a.area()</tt>. | ||
480 | </p> | ||
481 | |||
389 | <h2 id="idioms">Translating C Idioms</h2> | 482 | <h2 id="idioms">Translating C Idioms</h2> |
390 | <p> | 483 | <p> |
391 | Here's a list of common C idioms and their translation to the | 484 | Here's a list of common C idioms and their translation to the |