Re: Overriding FFI ctype constructors?

  • From: Mike Pall <mike-1206@xxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Fri, 8 Jun 2012 12:54:32 +0200

Claire Lewis wrote:
> Is there some way to provide my own constructor for a ctype in
> FFI? Specifically for an opaque type that I have a C call to
> create, such as:
> 
>   ffi.cdef[[
>     struct OpaqueType;
>     struct OpaqueType *NewOpaqueType();
>     ...
>   ]]
> 
>   OpaqueType = ffi.typeof("struct OpaqueType;")
> 
>   myot = OpaqueType(); -- error, unknown size
> 
> Ideally, I'd like to be able to set up OpaqueType to call
> NewOpaqueType(), or a Lua function so I can do the same, and
> massage arguments as needed.

Well, types don't have user-definable constructors in C, either.

[They do in C++. But C++ support isn't on the horizon, yet.]

In the general case, you'll want access to plain object creation
(if the size is known) or to one of several user-defined
constructors. Now, how do you differentiate those cases? If you
can override the default constructor with your own function, then
how do you create the object inside of that function, if needed?

I don't see a convincing solution, other than explicitly naming
constructors. But then we're back to square one.

> Currently I'm doing so by doubling up symbols:
> 
>   _OpaqueType = ffi.typeof("struct OpaqueType;") -- type
>   OpaqueType = ffi.test.NewOpaqueType -- constructor
> 
> But this is not as clean as I would like; I'd prefer to have the
> ctype still be represented by the same name, as with other
> structs.

I can see the benefit of orthogonality. But then ... the user of
such a type doesn't really need the ctype. They should never
instantiate it themselves. And in fact, they cannot do this for an
incomplete struct, anyway.

I'd redefine the problem as 'give me a constructor for every type'
as opposed to 'give me a ctype for every type'. Then you can
return either the ctype (which works as a constructor) or an
explicit constructor function. The user of the library doesn't
need to care, they just write 'local o = OpaqueType()'.

--Mike

Other related posts: