[gambit-list] Anyone else working in a schemey wrapper for c structs/unions/types?

Mikael mikael.rcv at gmail.com
Wed Dec 25 19:21:58 EST 2013

https://github.com/feeley/gambit/pull/61 - for a quick proof of concept,
that's a very neat use of the ffi type!!!

2013/12/25 Estevo <euccastro at gmail.com>

>  I have never been aware of anything like that. Can you provide a proof
>> of concept example code that shows how weak references to a FFI object
>> would be inconsistent?
> The problem is not that they're inconsistent.  The problem is they can't
> really tell you when an object that is depended upon is safe to free.  I
> gave an example of that in this thread:
> https://mercure.iro.umontreal.ca/pipermail/gambit-list/2013-December/007335.html

So you tried to somehow use wills to force GC order? Without having studied
this, I guess that was not what they were intended for in the first place
and it makes good sense that that did not work out well.

>> You can implement this kind of behavior in Gambit (i.e. B is referenced
>> to by or actually contained in A so you want freeing of B to be conditioned
>> to the freeing of A happening before) yourself, for instance by
>>  1) ensuring you have a reference to B in some vector or alike, one that
>> guaranteedly will stick around until A is freed. Also, you could
> Once user code gets hold of A, pure Scheme code can't really know when
> it's OK to let go of that vector.  It's the same problem.  Of course you
> can keep a reference forever, but you don't want to hold on to unneeded
> memory either.

You should be able to work that out and question is just how heavy it would
be implementation-wise to do, no??

If not why not?

>   2) use the "refcount" facility that Gambit exports to the C world, to
>> keep B's refcount +1 as long as A refers to it, and then have A's release
>> procedure -1 its refcount on invocation.
> Something like this might work, thanks!  I had given up on foreign release
> functions because they are C functions that can only be set (or so I
> thought) per foreign object type (the ones you create in c-define-type) and
> not per instance, they can't be closures, and they won't get any arguments
> but the foreign's pointer to C data.  Also, you can only set one, so if you
> use it for this you can't use it for anything else.
> But these restrictions need not be showstoppers.  A scheme that might work:
>  - on initalization, create an ___alloc_rc'ed table[1] and assign a global
> C pointer to it
>  - whenever you create a dependent foreign pointer F, store in the table a
> reference to its dependent object D, keyed by the address of the F's C
> pointer, and
>  - set a release function for F that will clear that entry in the table.

Why do you need a "table" (by table here you mean resizable vector)?

> This should work because unlike wills, release functions will only be
> called when their object is not reachable from Scheme code (barring FFI
> black magic).
> What practical task are you solving?
> I'm making a library that lets you define C struct/union/type
> constructors, accessors and mutators using a syntax analogous to that of
> define-structure.


Gambit's builtin functionality for this is fully sufficient at Gambit's
level of abstraction over the underlying system, and indeed there's plenty
of space for higher-level abstractions that more in this area.

So the totality of what you are looking to provide is

 a) the c-struct form which is analogous to define-type with

 b) Scheme-like automatic dependency GC-reference handling between c
structure instances as discussed here


>  Here's how you define C structure wrappers:
> https://github.com/euccastro/gambit-SDL2/blob/master/c-test-ffi.scm
> and here's how you use them
> https://github.com/euccastro/gambit-SDL2/blob/master/test-ffi.scm
> Here's a non-test example:
> https://github.com/euccastro/gambit-SDL2/blob/master/sdl.scm
> This is from a very old version and it shows that I didn't know what I was
> doing :), but it does showcase the user interface.  The point is that using
> C structures from Gambit code should be effortless, straightforward, safe,
> and fit well both with Scheme and with FFI code that doesn't follow your
> approach.
> I'll give the scheme above a go and let you know how it goes.  I think the
> solution involving my patch[2] should yield better performance because it
> doesn't involve any table following and,

> not requiring the use of release functions,

well, if it's some exotic type where you need C code invoked for the
release work then indeed there is the need for a release function, however
if that's not the case then yep right, with this model you suggest, there's
no need for a release function.

> allows you to set the last parameter of c-define-type to false.  But maybe
> this won't matter in practice.
> Thanks again!
> [1] Globals won't do because the garbage collector doesn't scan those.
> Movable objects won't do because you can't reliably keep a C pointer to
> them.
> [2] Which, by the way, I've simplified down to a 5-line change.  See
> https://github.com/feeley/gambit/pull/61
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20131226/3c4f3a26/attachment.htm>

More information about the Gambit-list mailing list