lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Florian Weimer wrote:
> I think it could be useful if you could create a cdata/userdata
> combination.  This would allow access to the blob in a userdata as a C
> structure, and you could still provide an object-specific metatable.

The FFI treats userdata like a 'void *' pointing to the payload.
So you can assign or cast it to a pointer to a struct and then
access its fields:

  ffi.cdef[[
  typedef struct { int x; } foo_t;
  ]]
  local tostruct = ffi.typeof("foo_t *")
  local function inc_x(ud)
    local s = tostruct(ud)
    s.x = s.x + 1
  end

> I think this is surprising (to a C++ programmer at least):
>
> | Objects which are passed as an argument to an external C function
> | are kept alive until the call returns.
>
> I think the lifetime should extend to full expression, that is, beyond
> the call.  The reason is that a function might return a pointer that
> is passed in, such as:
>
>   char *check_string(char *);
>
> If this is called as
>
>   do_something(check_string(ffi.new(...)))
>
> then the returned pointer will not keep the original pointer live.

There's no way to do that, since the bytecode doesn't have any
concept of sequence points. And the FFI knows nothing about the
bytecode, too.

In general, the VM makes no attempt to infer the lifetime of
pointers to allocated objects. That's pretty hopeless, anyway.

The FFI has a strict 'no hand-holding' policy. If you want to keep
some object alive, then assign it to a local variable:

  do
    local a = ffi.new(...)
    do_something(check_string(a))
    ...
  end -- 'a' is not GC'ed before here

--Mike