[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-users] idiom question

From: felix
Subject: Re: [Chicken-users] idiom question
Date: Sun, 6 Oct 2002 22:57:55 +0200

>> I have a question concerning an idiom I want to do in the C FFI.
>Ok, this is the best I've found so far:
>(require 'srfi-4)
>(define foo (s32vector 42))
>(foreign-declare #<<EOF
>int foobar(int *p)
>    int old = *p;
>    *p += 1;
>    return(old);
>(define foobar
>    (foreign-lambda int "foobar" s32vector))
>(let ((f (foobar foo)))
>    (print f " " (s32vector-ref foo 0)))

Yep, that's the approach I would normally use. As an alternative,
you can use locatives, which are nearly identical to foreign pointers.
(Note that this needs some minor changes in the system, mainly
relaxing type-checks to allow locatives in places where pointers
are normally required):

(define foobar
  (foreign-lambda int "foobar" (pointer int)) )

(let* ([box (s32vector 42)]
         [f (foobar (make-locative box 0))] )
  (print (cons f (s32vector-ref box 0))) )

Nothing much is gained here, but this allows passing
pointers to arbitrary elements of the container
(if the container allows unboxed/untagged contents).

>Can anyone do better? Idealy, I want to take out the explicit s32vector if I
>can. I just want this to work:
>(define foo 42)
>(let ((f (foobar foo)))
>    (print f " "  foo))
>and get :
>42 43

This won't really work: the argument `foo' is passed call-by-value,
and only making `foobar' a special-form would allow this syntax.
An alternative might be something like:

(let ([f (foobar (location foo))]) ...)

The special form `(location <variable>)' could be used to create
a locative that refers to the contents of <variable>. The problem here
is that we have to tell the foreign-lambda that the location
points to a boxed/tagged element. This means the client code
has to handle the conversion, otherwise we have to pass a pointer
to a temporary location and copy the value into the target location
later, which is ugly and somehow defeats the original intention (IMHO).

Or: have variables with unboxed/untagged contents:

(define-external foo int 42)

(let ([f (foobar (external-pointer foo))])

Still slightly kludgy, and one currently can't have non-toplevel
external variables. But the machinery is there, we just need some
syntax for this, a la:

(define-location foo int 42)   ; like `define-external', but doesn't create a 
globally named `foo'
(let ([f (foobar (location foo))])

What do you think? Any comments would be welcome.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]