[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: LuaJIT FFI cdata introspection
- From: Alexander Nasonov <alnsn@...>
- Date: Tue, 1 May 2012 03:35:05 +0100
Leo Razoumov wrote:
> Michal,
> were you able to make FFI introspection work the way you wanted? If
> yes, could you, please, provide the latest version of the patch you
> posted to the Lua mailing list back in February 2011.
>
> Thanks,
> --Leo--
I'd like to bring up the topic and paste my hack for those who don't
want to modify luajit binary.
Alex
local ffi = require 'ffi'
local defs = [[
struct A {
int16_t a;
int16_t b;
char c[7];
} __attribute__((packed));
struct B {
char a[6];
int16_t b;
int16_t c;
int8_t d;
} __attribute__((packed));
]]
ffi.cdef(defs)
local member_candidates = {}
for w in string.gmatch(defs, '%w+') do
member_candidates[w] = true
end
local memorized_members = {}
local function members(obj, ct)
ct = ct or ffi.typeof(obj)
local f = memorized_members[ct]
if not f then
local om = {} -- {{offset, "member"}, ...}
for m,_ in pairs(member_candidates) do
local o = ffi.offsetof(ct, m)
if o then table.insert(om, {o, m}) end
end
table.sort(om, function(a, b) return a[1] < b[1] end)
local mms = {}
for i = 1, #om do
mms[i] = om[i][2]
end
f = function(obj)
local i = 0
return function()
i = i + 1
if i <= #mms then
local m = mms[i]
return m, obj[m]
end
end
end
memorized_members[ct] = f
end
return f(obj)
end
local pa = ffi.cast('struct A *', 'abracadabra')
local pb = ffi.cast('struct B *', 'abracadabra')
print('struct A:')
for k,v in members(pa[0]) do
print(k,v)
end
print('struct B:')
for k,v in members(pb[0]) do
print(k,v)
end
$ luajit test.lua
struct A:
a 25185
b 24946
c cdata<char (&)[7]>: 0x40269320
struct B:
a cdata<char (&)[6]>: 0x402731f8
b 24932
c 29282
d 97