Subject: [clisp-list] Re: FFI and C-POINTERs

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Tue Aug 3 11:39:04 2004

Hi,

First Pascal, I'm glad that you took the effort and started real code on this UFFI issue.

Some remarks / thoughts of mine:

o FFI:OFFSET 0 is your friend when you want to ignore size tests (I forgot about alignment behaviour).

o - How do I set a   FFI:UINT32 in the memory pointed to by M?
You need a #<foreign-variable>. All memory manipulations is via them.

o FFI:[:]FOREIGN-LIBRARY is your interface to dlopen() or MS-Windows LoadLibrary(). I believe it should be enough for UFFI.
Try to forget about directly interfacing to dlopen() or dlsym().

o please share your thoughts upon FOREIGN-POINTER vs. typed FOREIGN-VARIABLE objects. I was left under the impression that for UFFI, all functions with pointers (even strings) would have to be declared C-POINTER, so one would loose CLISP's ability to do conversion from e.g. Lisp strings internally, and everything would have to be done explicitly via
with-foreign-string or with-foreign-object.

o A critical point is that I don't know whether UFFI expects low-overhead switch for casts. In CLISP FFI:CAST is extremely expensive (quoted types could be done better).
Also, I haven't checked what UFFI implies w.r.t. the C-POINTER that you would have to use in function definitions and possible memory dereference when you want to access fields from pointers and you thus need foreign-variable objects.

That's why ffi:allocate-shallow yields a typed foreign-variable, whereas a UFFI:malloc interface can only yield a c-pointer.

o If you only need foreign-variable objects, then don't invoke malloc and friends (via allocate shallow).
A common way is to use WITH-FOREIGN... to get a foreign-variable object.

I think I once posted a FOREIGN-VARIABLE constructor hack code in Lisp. I believe a FOREIGN-VARIABLE and FOREIGN-FUNCTION constructor would be a useful addition. I didn't provide one because (of time and) I'm always hit by that internal/external parse-c-type foreign-pointer issues. The constructor must accept the internal type representation.

(with-c-var/foreign-object (x 'c-pointer (mymalloc))
  (cast ... 'ffi:uint)
Tell me if you're stuck and I'll provide code for a foreign-variable object with indefinite extent (remember SET-FOREIGN-BASE or whatever it got called).

o I didn't understand your SLIME backtrace.

o I really don't know whether using UFFI's interface CLISP can come out with efficient code. CAST etc. have a high penalty, whereas on native-code compilers they produce no-ops -- quite a difference.
But you probably want it to run first, then care about efficiency :-)

Regards,
	Jörg

---

From: Sam Steingold <[email-masked]>
Date: Tue Aug 3 12:24:03 2004

> * Hoehle, Joerg-Cyril <[email-masked]> [2004-08-03 20:37:48 +0200]:
>

this will extract the value of the pointer, not the datum to which the
memory points too:

(let ((m (c-malloc 4)))
  (print m)
  (unwind-protect
       (with-c-var (p 'c-pointer m)
         (print (cast p 'uint32)))
    (c-free m)))
    
#<FOREIGN-ADDRESS #x003F6B98> 
4156312 
4156312

#x003F6B98 ==> 4156312

to extract the number you need

(let ((m (c-malloc 4)))
  (print m)
  (unwind-protect
       (with-c-var (p 'c-pointer m)
         (print (cast p '(c-ptr uint32))))
    (c-free m)))

still, this is just access.  how does one _write_ to the memory returned
by malloc?

-- 
Sam Steingold (http://www.podval.org/~sds) running w2k
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.honestreporting.com>
Apathy Club meeting this Friday.  If you want to come, you're not invited.

---

From: Sam Steingold <[email-masked]>
Date: Tue Aug 3 12:49:01 2004

> (with-c-var/foreign-object (x 'c-pointer (mymalloc))

(let ((m (c-malloc 4)) ret)
  (unwind-protect
       (progn
         (with-c-var (i '(c-ptr uint32) m)
           (with-c-var (v '(c-ptr (c-array uint8 4)) m)
             (setq i 0)
             (push v ret)
             (setq i (1- (ash 1 32)))
             (push v ret)))
         (nreverse ret))
    (c-free m)))

*** - #<FOREIGN-ADDRESS #x003F6B98> cannot be converted to the foreign
       type UINT32

why uint32?! it's (c-ptr uint32)!

-- 
Sam Steingold (http://www.podval.org/~sds) running w2k
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.honestreporting.com>
main(a){printf(a,34,a="main(a){printf(a,34,a=%c%s%c,34);}",34);}