chicken-users
[Top][All Lists]
Advanced

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

Re: [Chicken-users] Basic FFI Principle in Chicken


From: Peter Bex
Subject: Re: [Chicken-users] Basic FFI Principle in Chicken
Date: Fri, 6 Sep 2013 09:07:36 +0200
User-agent: Mutt/1.4.2.3i

On Fri, Sep 06, 2013 at 08:52:08AM +0200, Chris Mueller wrote:
> Hi,

Hi!

> i've currently started experimenting with the FFI interface provided by 
> the chicken compiler and have some principle questions about its common 
> usage.

Sure, no problem.  One important thing to remember is that there are
many, many ways to accomplish the same task using the FFI.  Which way
you choose depends on the C API you're binding to, your personal
preferences, performance concerns and your/your users' convenience.

> Assume the given C Code:
> 
> struct color {
>   int red;
>   int green;
>   int blue;
>   int alpha;
> };
> 
> struct color* alloc_new_color(int red, int green, int blue, int alpha);
> 
> 1) How do you interface allocation methods in generell with avoidance of 
> memory leaks?
> 
> From the documentation i know, you can write:
> 
> (define-foreign-type color* (pointer (struct "color"))))
> 
> (define alloc_new_color (foreign-lambda color* "alloc_new_color" integer 
> integer integer integer))
> 
> But this expects the user have to free the memory manually.
> 
> Is there an uncomplicated way to register some automechanism?

Yes, look into register-finalizer! which is documented here:
https://wiki.call-cc.org/man/4/Unit%20library#set-finalizer

However, finalizers incur quite a performance penalty.  It may be
wiser to simply make-blob for registering the memory used by a
color struct.  This will be managed by the garbage collector directly.
Example:

(make-blob (foreign-value "sizeof(struct color)" int))

If you want to expose this outside of your module, it's wise to wrap
it in a unique record type, so that you don't accidentally mix up blobs
of different "types":

(define-record color blob)
(define alloc-color (make-color (make-blob (foreign-value "sizeof(struct 
color)" int))))

Depending on how the colors are used you can also decide never to work
with C color "objects" directly, but decode them yourself like in

(define-record color red green blue)

and then pass this around, converting to struct color when needed.

> 2) How can i solve this problem:
> 
> void rgb_to_hsl(struct color* rgb, float* hue, float* sat, float* lum);
> 
> This is simple conversation method that uses multiple return values 
> (hue, sat, lum).
> 
> How can i write a ffi define that accepts an argument of type "color*"
> and returns a scheme-vector with three elements?

As a small sidenote: it's possibly more idiomatic Scheme to return three
separate values instead of a compound vector type containing the three
values.  ie, (values 1 2 3) versus (vector 1 2 3)

If you go with the blob approach I sketched above, you can do something
like

(define (color->hsl color-blob)
  (let-locations ((hue float) (sat float) (lum float))
    ((foreign-lambda void "rgb_to_hsl" scheme-pointer
                    (c-pointer float) (c-pointer float) (c-pointer float))
      color-blob (location hue)(location sat)(location lum))
    (values hue sat lum)))

Possibly this may not compile cleanly, in that case you'd have to use a
foreign-lambda* and cast the scheme-pointer type to a color struct
pointer.

The idea is that locations allow you to locally define variables which
correspond to foreign types, for which you can request the memory
location so that you can use them when pointers are required.
The scheme-pointer type accepts various Scheme objects which have a
"data section".  This includes blobs, strings and a few other types.

For more info about locations, see https://wiki.call-cc.org/man/4/Locations
For more info about scheme-pointer, see
https://wiki.call-cc.org/man/4/Foreign%20type%20specifiers#scheme-objects

> Hope its not too basic for you. :)

Never, user questions are what this mailing list is for!  I hope my
answers make a little sense.

Cheers,
Peter
-- 
http://www.more-magic.net



reply via email to

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