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