2012-02-21 2 views
3

пример в учебнике раздел: «Определение метаметоды для типа С» выглядит следующим образом:LuaJIT параметр FFI конструктор маршрутизации

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) 

Я немного запутался, о том, где «конструктор» есть, я предполагаю, что по умолчанию point(3,4) - это маршрутизация неустойчивости 3 -> x и 5 -> y. Как насчет того, когда я хочу повесить какую-то логику на конструктор? По-другому. Как указать конструктор, отличный от стандартного?

Я обертываю кучу c-библиотек в объектно-ориентированный код lua, и я не забочусь о переносимости к каноническому lua. В частности, мне необходимо подключить три основные функции объектно-ориентированного программирования для управления жизненным циклом объекта, create, init, destroy. Я знаю, что уничтожить будет метод __gc моих типов 'metatable. Поэтому мне нужно знать, как сделать create и init, и, надеюсь, избежать инициализации по умолчанию, сделанной luajit.

редактировать

ffi.new и другие имеют кучу правил, регулирующих создание типов (задокументирована в семантике FFI в LuaJIT в). он находится в разделе семантики. Я все равно хотел бы знать, каким самым чистым способом будет встраивание пользовательских создателей и инициализаторов (входящих в состав библиотеки c) в создание объектов ffi.

ответ

3

Вы должны были бы обернуть point вызов, чтобы получить то, что вы хотите:

local function newpoint (vals) 
    -- Do stuff with vals here? 
    return point (vals) 
end 
newpoint {x=5;y=4} 

ИЛИ вы могли бы рассмотреть вашу функцию точки в качестве создания функции; и просто имеют метод init ...

mt.__index.init = function (p , x , y) 
    p.x = x; 
    p.y = y; 
end 

local mypoint = point() 
mypoint:init (1 , 2) 

Примечание; все объекты точечного типа уже имеют ваш метадаемый, поэтому вам не нужно прикладывать методы или что-то еще.

Мне кажется немного бессмысленным .... почему вы хотите отделить создание и инициализацию?

+0

Хахаха да, бессмысленно, оно продолжало пробегать по моей голове. Это класс, который создает объекты BSON/JSON. Существует метод init для сброса класса после создания документа. Тогда есть malloc/free create destroy. будучи программистом C -> C++ -> lua, я получил оленя в фаре: D –

+2

Небольшое полезное дополнение: заставьте метод init вернуть объект, на который он вызван, например: 'mt .__ index.init = function (p, x, x) px, py = x, y возвращает p end', поэтому вы можете сделать это: mypoint = point(): init (1, 3) '. Не очень важно, но довольно удобно (цепочка может сделать код очень аккуратным). – Deco

+0

Спасибо, deco, каждая идиома помогает: D –