Didn't find a guide to this in the wiki, mailing list archives, gambit.h comments or the examples directory that comes with Gambit. How do you build a Scheme list, vector, etc. in C and then return it to Scheme?
As a simple exercise to learn the FFI, I started by wrapping Unix uname(). That function fills a struct with a few null-terminated strings. It was easy to figure out how to return an individual string from C to Scheme but I'm stumped trying to return many of them at once in a list or a vector (or as multiple values).
I imagine this is done by calling the C constructors for the desired Scheme data types but I couldn't find those in <gambit.h>. There's ___BEGIN_ALLOC_VECTOR and ___END_ALLOC_VECTOR but I couldn't get those to work. Also ___make_vector but it takes some kind of ___processor_state argument. That and the lowercase name make it seem like an internal function that I shouldn't use.
If someone has the time to write a brief guide on constructing and returning lists/vectors/multiple values in C, it could be useful to others as well.
Afficher les réponses par date
The C interface chapter of the manual has some information about allocating Scheme objects from C code.
Stay away from ___BEGIN_ALLOC_VECTOR and friends, because these macros are meant for the code generated by the Gambit compiler and are tricky to use (some invariants known by the Gambit compiler need to be preserved).
Here are relevant functions from lib/mem.c for allocation of Scheme objects:
___SCMOBJ ___alloc_scmobj(___processor_state ___ps, int subtype, ___SIZE_TS bytes);
___SCMOBJ ___release_scmobj(___SCMOBJ obj);
___SCMOBJ ___make_pair(___processor_state ___ps, ___SCMOBJ car, ___SCMOBJ cdr);
___SCMOBJ ___make_vector(___processor_state ___ps, ___SIZE_TS length, ___SCMOBJ init);
The ___ps parameter is either NULL (to allocate a permanent object) or a processor state (to allocate a STILL object in that processor’s heap). The state of the current processor is accessible through the ___PSTATE macro. The subtypes are defined in include/gambit.h (for example ___sBOXVALUES is the subtype of boxes and multiple values).
STILL objects never move, and they have a reference count initialized to 1 and decremented by ___release_scmobj. When an object is no longer reachable by the GC *and* its reference count is 0, the object will be reclaimed.
For other types, such as Scheme structures, it is often easier to do the allocation in Scheme code and to pass a reference to it to the C code, and then have the Scheme code fill it in with the appropriate content.
Marc
On Aug 31, 2019, at 5:15 AM, Lassi Kortela lassi@lassi.io wrote:
Didn't find a guide to this in the wiki, mailing list archives, gambit.h comments or the examples directory that comes with Gambit. How do you build a Scheme list, vector, etc. in C and then return it to Scheme?
As a simple exercise to learn the FFI, I started by wrapping Unix uname(). That function fills a struct with a few null-terminated strings. It was easy to figure out how to return an individual string from C to Scheme but I'm stumped trying to return many of them at once in a list or a vector (or as multiple values).
I imagine this is done by calling the C constructors for the desired Scheme data types but I couldn't find those in <gambit.h>. There's ___BEGIN_ALLOC_VECTOR and ___END_ALLOC_VECTOR but I couldn't get those to work. Also ___make_vector but it takes some kind of ___processor_state argument. That and the lowercase name make it seem like an internal function that I shouldn't use.
If someone has the time to write a brief guide on constructing and returning lists/vectors/multiple values in C, it could be useful to others as well.
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://mailman.iro.umontreal.ca/cgi-bin/mailman/listinfo/gambit-list