type checks (was: CLISP typed foreign references)
"Hoehle, Joerg-Cyril" <[email protected]> Wed, 3 Apr 2002 15:42:19 +0200
| Newsgroups | gmane.lisp.uffi.general |
|---|---|
| Message-ID | <[email protected]> |
Hi,
> Well, thinking worse-is-better, I might suggest that you start with a
> typeless integer or do like CMUCL and wrap the address in a
> SAP object as an (unsigned-byte 32).
I'm currently thinking about:
;; not dissimilar to CMUCL with-alien
;; + (alien-funcall (extern-alien #) #)
(defun mygetenv (name)
;; with-allocation is yet to be implemented
(with-allocation ((varname ffi:c-string name))
;; (TYPE-OF varname) -> FOREIGN-VARIABLE
;; (describe varname) -> #<...> is a foreign-variable of type ...
(funcall ; <=> ffi::foreign-call-out
(foreign-address-function "getenv"
(resolve-foreign-name "getenv" nil nil)
(load-time-value (ffi::parse-c-type
;; l-t-v + parse-c-type to be hidden via nice macros
'(ffi:c-function
(:arguments (name ffi:c-pointer))
(:return-type ffi:c-string)
(:language :stdc)))))
;; foreign-address probably superfluous in future: just varname
(foreign-address varname))))
(resolve-foreign-name name library[foreign-pointer] os-option)
is what I'm currently thinking about as an interface
to dl_sym / GetProcAddress etc. (-> UNIX + MS-Windows + AmigaOS)
The above is buggy, since it would pass the address of the
string pointer instead of the address of the contents: char**. Hmm...
FOREIGN-VARIABLE objects already embody a pointer indirection.
It would work for gethostname using:
(defun mygethostname ()
(with-allocation ((buf (ffi:c-array-max character 256)))
(funcal ... (foreign-address buf) 256)
(ffi::foreign-value buf)))
To get the address of the ffi:c-string contents for getenv, I'd need
to do:
(ffi:foreign-value (%cast varname (ffi::parse-c-type 'ffi:c-pointer)))
This would read the c-string slot as a foreign-pointer, not as a string.
> BTW, ACL does both integer addresses and well as typed pointers.
> [...] For UFFI, I choose to use integer pointers for
> efficiency sake.
As soon as FOREIGN-POINTER objects were available in CLISP (~1995), I preferred to use them (in my AFFI).
1. I can use FINALIZE and do GC cleanup.
2. many pointers would not be represented as fixnums in CLISP, as
most-positive-fixnum -> 16777215 (in some configurations of CLISP - this is deep into its memory management)
so a bignum would have to be allocated anyway. So I prefered to yield predictable types and use dedicated objects consistently.
Regards,
Jorg Hohle.