At 23:54 +0200 2006/05/05, Marc Feeley wrote:
On 5-May-06, at 11:40 PM, Stephane Le Cornec wrote:
Gambit does not tolerate :: or <> in this form. Is there any reason why this wouldn't work, other than Gambit accepting the string?
No reason other than my lazyness. C++ names are a pain to parse. As a workaround use:
(c-declare "#define std_vector_int std::vector<int>") (c-define-type array-int "std_vector_int")
Ok. Although typedef is better here. (c-declare "typedef std_vector_int std::vector<int>")
I could typedef std::vector<int> into std_vector_int for that, but I lose genericity. The goal here is to use macro to generate interface to native C struct and handle arrays of structs. I seems much nicer to use lambda than to define the 8 conversion defines.
Has anyone used in Gambit native C calls that accept/fill struct arrays? How did you decide to handle this and why did you come to that conclusion?
I'm not sure what you mean.
== generic C interface Assuming Point is a C struct, we use a notation similar to records to define accessors:
(c-define-structure Point (x int) (y int))
; expands to:
(c-define-type Point (struct "Point")) (c-define-type Point* (pointer Point)) (define make-Point (c-lambda (int int) Point* "___result = new Point(___arg1, ___arg2);")) (define Point-x (c-lambda (Point*) int "___result = ___arg1->x;")) (define Point-x-set! (c-lambda (Point* int) void "___arg1->x = ___arg2;")) (define Point-y (c-lambda (Point*) int "___result = ___arg1->y;")) (define Point-y-set! (c-lambda (Point* int) void "___arg1->y = ___arg2;"))
Note that the underlying C struct definition takes care of alignment issues. (I think make-Point will leak memory, but I don't understand release-functions yet. The whole C-interface concept is difficult to understand.)
=== Array In a certain way, this is a generalisation of the Homogeneous vectors to any struct.
(c-declare #<<c-declare-end
void f() { Point z[8]; getpoints(z, 8);
moveto(z[0].x, z[0].y); lineto(z[1].x, z[1].y); }
c-declare-end )
; compare to:
(c-define-array Point-array Point) (c-define-array Point-array8 Point 8) (define (f) (let ((array (make-Point-array 8))) (getpoints array 8) (let ((p0 (Point-array-ref array 0)) (p1 (Point-array-ref array 1))) (moveto (Point-x p0) (Point-y p0)) (lineto (Point-x p1) (Point-y p1)))))
The 2nd implementation is much nicer. Not to mention that I'd hate to write the 8 macros to convert the array of Point to a list of pair (x y) and vice-versa.