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.