Re: Making FFI callbacks call free() automatically when it's collected

  • From: "Robert G. Jakabosky" <bobby@xxxxxxxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Thu, 19 Jul 2012 22:34:21 -0700

On Thursday 19, Johnson Lin wrote:
> 2012/7/20 Robert G. Jakabosky <bobby@xxxxxxxxxxxxxxx>:
> > On Thursday 19, Johnson Lin wrote:
> >> 2012/7/19 Mike Pall <mike-1207@xxxxxxxxxx>:
> > If the C callback has a related userdata value (void *) then you can
> > create one FFI callback instance for each C callback prototype and pass
> > a callback id as the userdata value.  The id would be used to lookup the
> > Lua callback function in a table.  Since the FFI callback slots are a
> > limited resource this would help decrease the number of slots needed.
> > 
> > local button_callbacks = {}
> > local function wrapped_button_cb(event, ud)
> > 
> >   local id = tonumber(ffi.cast("uintptr_t", ud))
> >   local cb = button_callbacks[id]
> >   if cb then return cb(event, id) end
> > 
> > end
> > local button_cb = ffi.new("ButtonCB", wrapped_button_cb)
> > 
> > local function wrap_button_cb(func)
> > 
> >   local id = #button_callbacks+1
> >   local ud = ffi.cast("uintptr_t", id)
> >   button_callbacks[id] = func
> >   return button_cb, ud
> > 
> > end
> > 
> > 
> > For UI callbacks it might be possible to do the callback lookup via a
> > widget id or the widget's cdata value.
> > 
> > --
> > Robert G. Jakabosky
> 
> Yes, thanks for the suggestion. I now just use:
> 
> local function cdata_addr(cd) return tonumber(ffi.cast("int", cd)) end
> 
> to produce the address' value, and use that as the key internally, to
> avoid the problem of cdata objects not suitable as the key directly.

I would use a cast to uintptr_t instead of int to support 64bit pointers.  
uintptr_t is guaranteed to be the same size as a pointer.

-- 
Robert G. Jakabosky

Other related posts: