I have been down this path before, with guile and with lua. Basically,
if C (or non-scheme) has a pointer to a scheme object, then you need to
hold a logical reference for it and protect the scheme object, and when
the C pointer is dropped decrease the refcnt.
I am unclear on the details of how you have a ref that gc is made aware
of. One way is to have a scheme array of the object and a count, and
have the code null out the object when the count goes to zero or
something like that. But the point is that you need to have a proxy in
the scheme world, visible to gc, when a pointer to a scheme object is
held outside of the scheme world.
That's more or less what I had in mind, although instead of an array I would use a hash table indexed by a fundamental type (e.g. integer) which can be converted painlessly between Scheme and C.
Forcing gc is not going to be reliable. If you have a reliable scheme,
gc can happen at any random time and things will be ok.
I prepared a minimal case of the kind of C interactions that I'm trying. I'm attaching the files, the C code has to be compiled with:
gcc -shared -fPIC -o mysalsa.so mysalsa.c
Running the Scheme script yields something like the following:
Captured: Closure without collection
Argument: noitcelloc tuohtiw erusolC
Captured: Closure with garbate collected
Argument:
So primitive values seem to be garbage collected, but closures are treated slightly differently. This is very interesting, since working with closures eliminates the need of those common "void *userdata" extra arguments.
Testing continuation is going to be interesting too.
Best regards.
--
Isaac Jurado
"The noblest pleasure is the joy of understanding"
Leonardo da Vinci