chicken-users
[Top][All Lists]
Advanced

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

[Chicken-users] chicken-bind: working with structs


From: Kristian Lein-Mathisen
Subject: [Chicken-users] chicken-bind: working with structs
Date: Thu, 24 May 2012 16:11:10 -0700


Hi guys!

I've been looking at chicken-bind's way of working with C-structs for a while now, and I'm in the works of something I think will be useful. I want to have chicken-bind generate code for struct-by-values. Thanks to all who helped me out in this tricky process!

Allocating memory for new structs
Chicken-bind needs to allocate structs:
1. In its "make-<struct>" construct
2. When a function returns a struct by value
3. When a struct has a struct field (aka nested structs, effectively a struct-by-value return type) 

I have decided to use make-blob to allocate memory in all cases because it's easy and seems to have very good performance. I haven't looked at the code, but I believe make-blob allocates on the stack whenever it can.

I have made a new version of chicken-bind's make-<struct> which now uses make-blob, replacing the old C_malloc. Please take a peek at https://github.com/kristianlm/chicken-bind/commit/f7dde10bdb40aa00ae776f23570aa1001ddde26d. I like the "set-point!" naming convention but I'm open to suggestions of course.

Struct-by-value return type =? locative
You typically have code like this:
struct point {float x,y};
float distance (point *a, point *b);

To use distance, you wanna do something like:
(distance (make-point 1 2) (make-point 2 3))

This means that all struct-bindings should return types compatible with pointers so they can be used seamlessly on the other functions. The only way I have found to achieve this is to return locatives. It's not ideal because you lose type information at runtime. Any ideas on how to keep this without forcing the user to convert? Do tagged locatives exist, like tagged pointers?

Struct by value return types

This is my proposal:
$ echo "struct point getPoint();" | chicken-bind  - -o - 
(begin
  (begin
    (begin
      (define getPoint/overwrite!
        (foreign-lambda*
          void
          (((c-pointer (struct "point")) dest))
          "*dest=(getPoint());"))
      (define (getPoint)
        (let ((dest (location
                      (make-blob (foreign-value "sizeof(struct point)" int)))))
          (getPoint/overwrite! dest)
          dest)))))

I wish to export the overwrite-version (and set-point! above) because I assume it can be useful in tight loops where you only need to allocate once. Any objections? And what might be a better name than /overwrite!?

Compatibility
The new patches should not change any behavior except that make-<struct> now returns a locative instead of a c-pointer.

Looking forward to hear your thoughts and get this patch out there!
Kris

reply via email to

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