Sorry for the self reply, I'm just not sure if my previous post was clear, so here's a commented version: local ffi = require('ffi') ffi.cdef"typedef struct foo_ foo_t;" -- LuaJIT has no idea how big this is ffi.metatype(ffi.typeof('foo_t'), { __index = { greet = function(self) print("Hey, ima:", self) -- Hey, ima: cdata<struct foo_ *>: NULL end } }) local f = ffi.new('foo_t*[1]') -- &opaque* (i.e. void*[1]) local g = f[0] -- opaque* (i.e. void*) g:greet() -- but this still works (i.e. LuaJIT rocks!) HTH -R