[racket-dev] ffi vectors

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu Sep 30 21:25:09 EDT 2010

I guess I misunderstood what you were looking for.

It would be nice to have a compact ctype that adapts like the C array
type to different contexts. For my FFI tasks, I've gotten by with
structure types like `_float4'; I manually choose between `_float4' or
`_float4-pointer' as needed in different contexts (the former for
`malloc' or a struct member, the latter for a function argument or
result). That strategy was was particularly awkward for a struct that
contained an array of 32 bytes, though.

At Thu, 30 Sep 2010 17:19:43 -0600, Jay McCarthy wrote:
> Yes, but this program:
> 
> typedef float float4[4];
> typedef struct {
>   float4 a;
>   float b;
> } astruct;
> 
> void go(float4 a, astruct b)
>  {
>   printf("in go: %d\n", sizeof(a));
>   printf("in go: %d\n", sizeof(float4));
>   printf("in go: %d\n", sizeof(b));
>   printf("in go: %d\n", sizeof(astruct));
> 
>  }
> 
>  int main() {
>   float4 a;
>   astruct b;
>   printf("in main: %d\n", sizeof(a));
>   printf("in main: %d\n", sizeof(float4));
>   printf("in main: %d\n", sizeof(b));
>   printf("in main: %d\n", sizeof(astruct));
>   go(a, b);
>  }
> 
> produces
> 
> in main: 16
> in main: 16
> in main: 20
> in main: 20
> in go: 8
> in go: 16
> in go: 20
> in go: 20
> 
> The FFI is not just used for making function calls, it is also used
> for specify structures and malloc-ing on behalf of the functions you
> want to call. It is very awkward to make cstructs that are the correct
> size and malloc the right amount without similar functionality to C in
> this regard.
> 
> Jay
> 
> On Thu, Sep 30, 2010 at 4:51 PM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
> > When you run this program on a 32-bit machine:
> >
> >  #include <stdio.h>
> >
> >  void go(float a[4])
> >  {
> >   printf("in go: %d\n", sizeof(a));
> >  }
> >
> >  int main() {
> >   float a[4];
> >   printf("in main: %d\n", sizeof(a));
> >   go(a);
> >  }
> >
> > you'll see "in main: 16" and "in go: 4".
> >
> > As far as I know, the "4" in " void go(float a[4])" is ignored. It's
> > really the same as "void go(float a[])" or "void go(float *a)". Unless
> > the declaration of an array variable is allocating the variable, the
> > variable is really a pointer, and sizeof() reflects that.
> >
> > Along the same lines, a `_cvector' in the FFI always has a pointer
> > size, because it's always like a pointer.
> >
> > A `(_cvector o _float 4)' or `(_f32vector o 4)' is probably
> > what you want, if the function you'll calling fills in the vector. A
> > `_float4-pointer' (not `_float4'!) if you allocate it yourself or
> > `(_pointer o _float4)' is also fine.
> >
> >
> > At Thu, 30 Sep 2010 16:41:29 -0600, Jay McCarthy wrote:
> >> I'd like to be able to define ctypes like I would make a typedef in C like
> >>
> >> typedef float           float4[4];
> >>
> >> But it doesn't seem like this works in the FFI. See the program below
> >> with its awkward work-around:
> >>
> >> #lang racket
> >> (require ffi/unsafe
> >>          ffi/unsafe/cvector
> >>          ffi/vector
> >>          tests/eli-tester)
> >>
> >> (test
> >>  (ctype-sizeof _float) => 4
> >>
> >>  (ctype-sizeof _cvector) => 4
> >>  (ctype-sizeof (_cvector i _float)) => 4
> >>  (ctype-sizeof (_cvector o _float 4)) => (* 4 4)
> >>  (ctype-sizeof (_cvector io _float 4)) => (* 4 4)
> >>
> >>  (ctype-sizeof _f32vector) => 4
> >>  (ctype-sizeof (_f32vector i)) => 4
> >>  (ctype-sizeof (_f32vector o 4)) => (* 4 4)
> >>  (ctype-sizeof (_f32vector io 4)) => (* 4 4)
> >>
> >>  (local [(define-cstruct _float4
> >>            ([f0 _float]
> >>             [f1 _float]
> >>             [f2 _float]
> >>             [f3 _float]))]
> >>    (test
> >>     (ctype-sizeof _float4) => 16)))
> >>
> >> Output is:
> >>
> >> test: 5/11 test failures:
> >> unsaved-editor4119:11:1: test failure in (ctype-sizeof (_cvector i _float))
> >>   expected: 4
> >>        got: error: expand: unbound identifier in module
> >> unsaved-editor4119:12:1: test failure in (ctype-sizeof (_cvector o _float 
> 4))
> >>   expected: 16
> >>        got: 4
> >> unsaved-editor4119:13:1: test failure in (ctype-sizeof (_cvector io _float 
> 4))
> >>   expected: 16
> >>        got: error: expand: unbound identifier in module
> >> unsaved-editor4119:17:1: test failure in (ctype-sizeof (_f32vector o 4))
> >>   expected: 16
> >>        got: 4
> >> unsaved-editor4119:18:1: test failure in (ctype-sizeof (_f32vector io 4))
> >>   expected: 16
> >>        got: error: expand: unbound identifier in module
> >>
> >> Normally I would just go do this, but I don't really understand the
> >> FFI. If someone can point me appropriately, I'll go do it.
> >>
> >> Jay
> >>
> >> --
> >> Jay McCarthy <jay at cs.byu.edu>
> >> Assistant Professor / Brigham Young University
> >> http://teammccarthy.org/jay
> >>
> >> "The glory of God is Intelligence" - D&C 93
> >> _________________________________________________
> >>   For list-related administrative tasks:
> >>   http://lists.racket-lang.org/listinfo/dev
> >
> 
> 
> 
> -- 
> Jay McCarthy <jay at cs.byu.edu>
> Assistant Professor / Brigham Young University
> http://teammccarthy.org/jay
> 
> "The glory of God is Intelligence" - D&C 93


Posted on the dev mailing list.