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

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Thu Aug 5 07:46:13 2004

Sam wrote:

>(let ((m (c-malloc 4)) ret)
>  (unwind-protect [...]
>    (c-free m)))
That's what WITH-... (the foreign stack allocators) are for.
I wouldn't want to review code with such a construct in it.
I hope it was just to setup an example?!?

>         (with-c-var (i '(c-ptr uint32))
>           (setf (cast i 'c-pointer) m)
>           (setq i (1- (ash 1 32)))
>           (push v ret)
That's the ugliest piece of Lisp(is that Lisp?) code I've seen in ages!

>since here we see that the answer depends on endianness,
>I propose adding :LITTLE-ENDIAN or :BIG-ENDIAN to *FEATURES*.
I see no need. Better add interfaces to ntohl() etc. if that's needed for networking (is the problem at all about networking??)

>> BTW, what are you trying to achieve?
>Pascal asked this first.
I haven't seen where. If you mean
>- Same questions for the (FFI:C-ARRAY (2) FFI:UINT16)?
then I believe he has enough elements to the solution now.
I suppose Pascal is amid UFFI, but I haven't seen more context.

>when is FOREIGN-VALUE useful?  why is it exported?
> [...] but when is it used standalone?
I consider it part of a layered API which the current impnotes does not yet reflect. When you work at a level where FOREIGN-VARIABLE becomes visible and useful, then FOREIGN-VALUE is your friend.
Of course, one can easily switch to a higher level using
WITH-C-PLACE to operate using the higher-level API, which is currently the only one to export SLOT, ELEMENT, CAST etc.
In my experience, code written using the higher-level API is a little shorter since it doesn't need an explicit FOREIGN-VALUE. Conversion is implicit.

However, certain things are not possible using the higher-level API, e.g. store a foreign-variable (i.e. a reference) object somewhere, instead of a Lisp copy.

Regards,
	Jorg Hohle.

---

From: Sam Steingold <[email-masked]>
Date: Thu Aug 5 08:20:01 2004

> * Hoehle, Joerg-Cyril <[email-masked]> [2004-08-05 16:45:42 +0200]:
>
> Sam wrote:
>

this is an example of a code which receives a pointer from the "outside"
(malloc) and then accesses the memory it refers to alternatively as
uint32 and int8[4].

> That's the ugliest piece of Lisp(is that Lisp?) code I've seen in ages!

how would you express these conversions?
please offer some _code_ which is equivalent to the following C:

  uint32 i;
  uint8 *p = &i;

  p[0] = 1; p[1] = 2; p[2] = 3; p[3] = 4;
  ASSERT(i == (1<<24) + (2<<16) + (3<<8) + 4);

> I see no need. Better add interfaces to ntohl() etc. if that's needed
> for networking (is the problem at all about networking??) 

IIUC, the result of my form is

(let ((m (c-malloc 4)) ret)
  (unwind-protect
       (with-c-var (v '(c-ptr (c-array uint8 4)))
         (setf (cast v 'c-pointer) m)
         (with-c-var (i '(c-ptr uint32))
           (setf (cast i 'c-pointer) m)
           (setq i 0)
           (push v ret)
           (setq i (1- (ash 1 32)))
           (push v ret)
           (setq v #A((unsigned-byte 8) (4) (1 2 3 4)))
           (push i ret))
         (nreverse ret))
    (c-free m)))
==>
(#A((unsigned-byte 8) (4) (0 0 0 0))
 #A((unsigned-byte 8) (4) (255 255 255 255))
 #+little-endian ; i386
 #.(+ (ash 4 24) (ash 3 16) (ash 2 8) 1)
 #+big-endian ; sparc
 #.(+ (ash 1 24) (ash 2 16) (ash 3 8) 4))

is this correct?

if it is, and a valid CLISP form can produce different results on
different hardware, then this calls for a *FEATURES* entry.

if it's not, please explain to me what endianness is about.

thanks.

> I consider it part of a layered API which the current impnotes does
> not yet reflect. When you work at a level where FOREIGN-VARIABLE
> becomes visible and useful, then FOREIGN-VALUE is your friend. 
> WITH-C-PLACE to operate using the higher-level API, which is currently
> the only one to export SLOT, ELEMENT, CAST etc. 
> In my experience, code written using the higher-level API is a little
> shorter since it doesn't need an explicit FOREIGN-VALUE. Conversion is
> implicit. 
>
> However, certain things are not possible using the higher-level API,
> e.g. store a foreign-variable (i.e. a reference) object somewhere,
> instead of a Lisp copy. 

please write this up, with examples, preferably DocBook/XML (but plain
text is also good enough)

-- 
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>
He who laughs last did not get the joke.