[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: [LuaJIT FFI] Issues with cdata/ctype
- From: Duncan Cross <duncan.cross@...>
- Date: Sun, 29 May 2011 15:18:48 +0100
Say I'd like to have a function which takes a value that represents a
buffer store of bytes, and returns two values:
- a value that can be ffi.cast to a void* (or other pointer)
- the number of bytes that this pointer-value points to
(1) If the input value is a string, the return values would be a
char[?] cdata with the contents of the string copied into it, and the
length of the original string. (The buffer would have an extra byte
added for the null terminator, but this would not be included in the
(2) If the input value is one of a set of special cdata types, the two
return values would be taken from ._ptr and ._byteLength fields on the
(3) If the input value is not one of one these special types, but it
*is* a cdata that is a struct or an array, the two return values would
be the original input value and ffi.sizeof the input value.
(4) Finally, if the input value (most likely a table) has a special
custom __tobuffer() metamethod on its metatable, this is called on it
to get the two values.
Hopefully this makes sense so far.
These are the issues I'm having with implementing this:
A. Determining 'one of a set of special cdata types' (2). I have tried
using tostring(ffi.typeof(value)) and looking this up in a table, and
it seems to work, but should I trust this method to be future-proof?
B. Determining whether a cdata is a struct/array (3) rather than, for
example, a void* pointer where ffi.sizeof would be the size of the
pointer rather than the size of what it's pointing to. Again, I have
thought of making use of tostring(ffi.typeof(value)) - seeing if it
begins with 'ctype<struct' or ends in ']>' - but this seems like an
even more fragile hack. It would be ideal if there were something like
a special field on ctype values to determine this.
Also, it strikes me that stage (2) would not be necessary if it were
possible to apply (4) to these cdata values instead of special-casing
them. I know there are heavy restrictions on the metatables of cdata,
and that is understandable. But I'm wondering if it would be possible
to call custom metamethods on cdata with something like a