low-level of UFFI (was: CLISP support)
"Hoehle, Joerg-Cyril" <[email protected]> Fri, 13 Dec 2002 18:29:48 +0100
| Newsgroups | gmane.lisp.uffi.general |
|---|---|
| Message-ID | <[email protected]> |
Matthew Danish wrote:
>UFFI does not currently support:
>foreign funcall of function pointers (or function pointer types, I
>think), out and in-out function arguments, casting, and callbacks.
CLISP has all of these. The problem for UFFI is probably how to define a common denominator.
>Also worth thinking about is an interface that is flexible enough to
>support run-time type and slot determination, but also be capable of
>compile-time optimization where possible.
I don't understand what you mean here. CLISP has FOREIGN-VARIABLE objects, and you can CAST at run-time, but this may not be what you're talking about.
>I'm hoping that I can collect all these features and formulate them
>better, sometime, possibly to be the basis of UFFI2.
Me too, since I alyways claimed that UFFI as it currently stands is incredibly low-level (C level). :in/out parameters etc. would help, variable-sized buffer support also.
Here's real code for CLISP:
(def-c-call-out execvp (:arguments (file c-string) (argv (c-array-ptr c-string)))
(:return-type int)
(:name "execvp"))
I'd like if somebody could show how to do this with UFFI, LW, ACL, CMUCL etc.
Here's hypothetical code (because of variable sized array):
;;http://cert.uni-stuttgart.de/doc/postgresql/escape/
(def-c-call-out PQescapestring (:name "PQescapestring")
(:arguments (length uint)
(to (c-ptr (c-array character (:length (1+ (* 2 length))))) :out)
(from c-string))
(:return-type uint))
; would really need distinct length for :in (from arg) and :out (from return code)
Actually I'm looking for a specification minilanguage. I discovered I need separate :in and :out length parameter recognition (one is size of array, another is how many actual elements), while the form used most of the time is that both collapse, which should be easily expressible.
Hypothetical CLISP code for variable sized arrays:
(def-c-call-out fgets (:arguments
(buf (c-ptr (c-array character ,size)) :out)
(size int)
(fp c-pointer))
(:return-type c-string))
; buffer size is taken from variable named size given as argument.
(multiple-value-bind (result buf) (fgets nbytes fp) (if result ...))
Here's another attempt at showing what I mean with UFFI being low-level. Compare what's below with http://uffi.med-info.com/manual/r1170.html
(def-c-call-out c-gethostname
(:arguments (name (c-ptr (c-array-max char 256)) :out :alloca)
(len size_t))
(:return-type int))
(defun gethostname ()
"Returns the hostname" ; probably no FQDN
(multiple-value-bind (result-code hostname) (c-gethostname 256)
(if (zerop result-code) hostname
(error "gethostname() failed."))))
See: no mucking around with allocate-foreign-stuff, convert-string and such. In many cases c-gethostname is already usable as is and doesn't need to be wrapped. In some sense, the description language is powerful enough to do most wrapping for you.
So what I'm calling for is even more macrology :)
Regards,
Jorg Hohle.