[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