[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: General discussion on Alien
- From: Duncan Cross <duncan.cross@...>
- Date: Tue, 2 Mar 2010 23:20:36 +0000
Hi List,
Recently I've been experimenting with Fabio Mascarenhas' excellent FFI library
Alien (version 0.5.0). It is very useful, but I found myself writing quite a
few notes about things as they came up, and thought I'd post them to the list.
I'd be interested to know whether other Alien users have hit the same things,
and if so, how they sorted them out.
* It's often valid to pass NULL for a callback, so allowing nil for function
parameters or struct fields of type 'callback' would be very useful, but
currently it causes an error:
--
setcallback = alien.mylib.setcallback
setcallback:types("void", "callback")
setcallback(nil) --> ERROR: bad argument #1 to 'setcallback'
(alien function or callback expected)
--
* Various 'ref' types are missing - 'ref pointer' in particular has come up
a lot for me, but also occasionally 'ref float' etc.
* Using alien.get(1, 'char') returns a signed value, which seems inconsistent
with all other use of 'char' where it is unsigned ('byte' is offered as
the signed alternative, so I assume 'char' *is* meant to be unsigned):
--
b = alien.buffer(1)
b:set(1, 255, 'char')
print( b:get(1, 'char') ) --> -1
--
* Is there any way to be able to pass a FILE* pointer inside a Lua file object
to an Alien function?
These are issues that I know how to get around, but still get caught out by
sometimes:
* If you assign an Alien callback to a field in a struct, it is not "pinned",
and can easily be accidentally left eligible for garbage collection:
--
mystruct_def = alien.defstruct{
{"mycallback", "callback"}
}
mystruct = mystruct_def:new()
function myfunction()
print("Hello World")
end
mystruct.mycallback = alien.callback(myfunction, {ret="void"})
collectgarbage() --> 'mycallback' gets garbage collected
--
* Forgetting to pass any second parameter to alien.callback() causes the
application to crash completely, rather than raising a normal error.
Finally, these are some subjective comments about the way Alien works:
* Using alien.buffer() on a light userdata works by changing the global
metatable for light userdata and returning it. This mainly isn't a problem -
though it does keep catching me out when I print() a light userdata for
debugging purposes and it tries to print arbitrary data - but it feels kind
of fragile and "unclean".
* It seems odd that if you want to get the pointer for a struct you should
call it like a function, but to get the pointer for an array you access
array.buffer. I find it way too easy to do the wrong one or forget to do
either. Could it be based on a __topointer() metamethod instead?
* I am not convinced it was a good idea to use 1-based offset parameters in
buffer:get(...) and buffer:set(...). I know that it might seem best to
remain consistent with Lua's 1-based indexing of strings and tables, but
my argument would be that there's a difference between an index and an
offset - while it may make sense to index from 1 (even if some folk don't
exactly care for it) it really *doesn't* make sense to offset from 1.
This difference is actually recognised in Lua's own standard libraries -
cf. the offset parameter of the file:seek() method.
-Duncan