[gambit-list] FFI with (char *) buffer

Phil Dawes pdawes at users.sf.net
Sun Feb 25 04:15:10 EST 2007

Hi Ben,

Ben Weaver wrote:
> Hello Everyone,
> I'm creating an FFI that requires writing to and reading from a C
> (char *) buffer.  The buffer may contain arbitrary binary data (not
> necessarily a character string).  I wrote a few procedures (see below)
> to copy the data to and from a u8vector so I can operate on it using
> ports.
> I'm hoping for comments or suggestions from you all about the code.
> Is there a cleaner/better/faster way to do this?  Ideally there would
> be some way to open a byte-port directly to the buffer so it wouldn't
> have to be copied.  Is this possible?

Here's my attempt (below).

N.B. I'm going out on a limb here because I'm certainly no expert on 
gambit internals - this is just from looking at the mem.c and gambit.h 
files. Also I'm not 100% sure the technique is portable to architectures 
that don't provide byte-addressable memory (e.g. ARM - can somebody 
confirm this?).

That said, here's the code (hopefully somebody else will point out if 
I've gone wrong). The 'create-still-u8vector' ensures that the u8vector 
won't be moved by the garbage collector and reduces the refcount so that 
it'll be properly garbage collected. 'put-some-bytes-in-still-u8vector' 
shows how to convert the vector to an addressable array (e.g. for 
loading files into etc..).

Hope this helps!


(define create-still-u8vector
   (c-lambda (int) scheme-object
   ___result = ___alloc_scmobj(___sU8VECTOR, ___arg1, ___STILL);
   ___EXT(___release_scmobj) (___result);

(define put-some-bytes-in-still-u8vector
   (c-lambda (scheme-object) void
   char *a;
   a = (char *)(___BODY_AS(___arg1,___tSUBTYPED));
   a[0] = 'h';
   a[1] = 'e';
   a[2] = 'l';
   a[3] = 'l';
   a[4] = 'o';

More information about the Gambit-list mailing list