[gambit-list] Gambit-list Digest, Vol 103, Issue 27
Estevo
euccastro at yahoo.com
Tue Apr 23 00:44:59 EDT 2013
> All of these issues can be abstracted in a macro for defining foreign
> structures. This is explained in the following message:
>
> https://mercure.iro.umontreal.ca/pipermail/gambit-list/2009-May/003475.html
>
> Marc
Geez, I so wish I'd found that one about one year ago, when I was trying to do the same thing! :)
My best effort attempt (don't use it! it never got out of playground/experimental stage)
was here:
https://github.com/euccastro/gambit-SDL2/blob/master/ffi-macro.scm
That one also tries to overcome the following issue, which Marc's macro (perhaps wisely)
leaves alone:
;; IMPORTANT NOTE: the foreign pointer returned by s2-coordinates-ref
;; is a pointer to a C struct within another C struct (the
;; "container"). The foreign pointer is only valid as long as the
;; container is allocated. Be wary that in the case of a C structure
;; allocated from Scheme, such as with a call to alloc-s2, the garbage
;; collector could reclaim the structure as soon as the foreign
;; pointer to it is dropped.
I tried to solve that problem by keeping a table of references with
weak keys corresponding to contained/child structs and strong values
corresponding to container/parent values.
The big problem was how to make the references table unique since it
was defined in macro-defining code, i.e., which was meant to be
included, not loaded. I suppose the cleaner solution would have been
to make a separate ffi library to `load`. I don't remember why I
didn't just do this. The hacky approach in that file (checking for
the current type of the symbol) seemed to work, but I guess that
relies on undocumented behavior.
In retrospect, that would have been made so much easier if you could
assign an arbitrary Scheme reference to a foreign pointer. I think
that would address a genuine need: in general, ffi pointers may point
to objects that 'depend' on other objects managed in the scheme world
(probably other ffi pointers), in such a way that it makes sense to
keep the dependencies alive while the pointer is in the scheme world.
Something like ___set_data_rc, but you can't use this function since
that messes with memory in the vicinity of the object pointed to;
most often, this memory belongs to the container/parent struct. So
it would need to be something like a Scheme call
(set-foreign-reference! pointer dependency)
that would set a ___SCMOBJ field in the foreign object itself. A
getter is not needed for this use case, but maybe it would enable
other uses (?).
Alternatively, there could be a different type of foreign object
that has this functionality, so applications that don't use it
won't incur the space cost of the additional pointer.
More information about the Gambit-list
mailing list