On 7/28/07, Stelian Ionescu sionescu@common-lisp.net wrote:
- return multiple arguments, the first one being the foreign function's
return value(if it's not "void"), the rest being the struct members unpacked. this has the advantage of being mainly non-consing - except maybe for large numbers of values - IIRC with stat() I get 14 multiple values. If I'm not mistaken most implementation stack-allocate multiple values(perhaps only up to a certain number ?)
This is good for some things with a sane number of values -- like pipe(). For others like stat() less so. Returning a "handfull" of values tends to be very fast, yes.
- copy each struct into a structure object or CLOS object(like
sb-posix). this has the disadvantage of consing one or more objects with each call.
Yeah. You forget the possibility of using an optional argument to pass in a pre-allocated object, though:
(let ((stat (make-instance 'stat))) (loop for f in paths do (frob (stat path stat))))
- make two packages: one with an interface very close to C, without
unpacking or consing objects, ie. STAT would need to be passed a foreign pointer to a "struct stat" and the programmer would use directly CFFI to retrieve desired data. the second interface would be a high-level one, lispy in the sense of having ENVIRONMENT-VARIABLE and (SETF ENVIRONMENT-VARIABLE) instead of GETENV and SETENV. the function names would be quite different from the OS names also because we could have something like (SETF FILE-STAT) as "frontend" for several syscalls such as chown, chmod and utime (example taken from http://clisp.cons.org/impnotes/syscalls.html).
in all 3 options I imply reporting errors via conditions
the choice I prefer is n° 3, because it allows me to have both a (mostly) non-consing interface for when I really need speed and a lispy interface that *most* people would want to use since dealing with a FFI is most often obnoxious, and yes, I'm a bit obsessed by speed/efficiency :)
among existing libraries, OSICAT seems to be the one closer to what I prefer and we(luis and I) have been thinking of continuing development of OSICAT if you agree, abandoning iolib-posix on favour of something like osicat-posix-ffi and osicat-windows-ffi - the low-level side of it
I havent' worked actively on Osicat for a while (which is not to say I've abandoned it, but rather that I'm very happy to pass out commit bits...), so my gut feelings are not too well trained here, but...
YES!
OSICAT: something very much like now, including pathname functions like NATIVE-NAMESTRING and PARSE-NATIVE-NAMESTRING. Nice and lispy, portable across multiple platforms -- either using interfaces that are flexible enough, or staying clear of platform specific hair even when it means missing functionality.
WIN32-SYS & POSIX-SYS: low-level APIs. Should be possible to use without thinking about "CFFI", or "Alien", or whatever the FFI layer is. As high-level as possible while remaining an accurate mapping and as low-level as it needs to be for the needs of accuracy and efficiency.
My 0.02EUR.
Cheers,
-- Nikodemus