2016-07-22 2 views
1

Итак, я пытаюсь создать модуль, который динамически обнаруживает, если вы используете Lua или LuaJIT, и создает таблицу или cstruct в зависимости. Так как вы не можете добавить метатеги к изображениям, у меня есть массив с именем _m в моей структуре.Индекс массива внутри структуры FFI

Вот фрагмент соответствующего кода, я свяжусь с Git repo ниже.

local mat4  = {} 
local mat4_mt = {} 

-- Private constructor. 
local function new(m) 
    m = m or { 
     0, 0, 0, 0, 
     0, 0, 0, 0, 
     0, 0, 0, 0, 
     0, 0, 0, 0 
    } 
    m._m = m 
    return setmetatable(m, mat4_mt) 
end 

-- Do the check to see if JIT is enabled. If so use the optimized FFI structs. 
local status, ffi 
if type(jit) == "table" and jit.status() then 
    status, ffi = pcall(require, "ffi") 
    if status then 
     ffi.cdef "typedef struct { double _m[16]; } cpml_mat4;" 
     new = ffi.typeof("cpml_mat4") 
    end 
end 

function mat4.transpose(out, a) 
    out[1] = a[1] 
    out[2] = a[5] 
    out[3] = a[9] 
    out[4] = a[13] 
    out[5] = a[2] 
    out[6] = a[6] 
    out[7] = a[10] 
    out[8] = a[14] 
    out[9] = a[3] 
    out[10] = a[7] 
    out[11] = a[11] 
    out[12] = a[15] 
    out[13] = a[4] 
    out[14] = a[8] 
    out[15] = a[12] 
    out[16] = a[16] 

    return out 
end 

mat4_mt.__index = function(t, k) 
    if type(t) == "cdata" then 
     if type(k) == "number" then 
      return t._m[k-1] 
     end 
    elseif type(k) == "number" then 
     return t._m[k] 
    end 

    return rawget(mat4, k) 
end 

function mat4_mt.__call(_, a) 
    return new(a) 
end 

if status then 
    ffi.metatype(new, mat4_mt) 
end 

return setmetatable({}, mat4_mt) 

Проблема здесь в том, что, когда я пытаюсь вызвать транспонирование, я получаю следующее сообщение об ошибке:

'struct 173' cannot be indexed with 'number'

Если вы заканчивали mat4_mt.__index, я пытаюсь определить, какой тип я работаю с, table или cdata и индексировать массив внутри структуры.

local mat4 = require "mat4" 
local a = mat4() 
local b = mat4():transpose(a) -- Error! 

Идея заключается в том, что при попытке доступа, скажем, a[4], он должен быть доступ к a._m[3] за кулисами, но это явно не происходит, и я понятия не имею, почему.

Мысли?

https://github.com/excessive/cpml/blob/refactor/modules/mat4.lua

+0

Вышеупомянутый код не работает, как указано. Мне пришлось заменить 'return new (a)' на 'return new (a или {})'. Ссылка больше не действительна. Я нашел это при поиске сообщения об ошибке, поэтому, возможно, ответ по-прежнему ценен. –

ответ

0

Это работает, но не хватает __newindex метатаблицы записи, вызывая out[index] = value на неудачу, потому что он все еще пытается индексировать-структуру, а не поля он содержит. Добавление этого исправляет проблему:

mat4_mt.__newindex = function(t, k, v) 
    if type(t) == "cdata" then 
     if type(k) == "number" then 
      t._m[k-1] = v 
     end 
    elseif type(k) == "number" then 
     t._m[k] = v 
    else 
     rawset(t, k, v) 
    end 
end 
Смежные вопросы