[plt-scheme] Bug report / request for comment concerning foreign.ss
On Nov 4, Ernie Smith wrote:
> (module ffi-bug mzscheme
> (require (lib "foreign.ss" )) ;; (unsafe!)
> ;;
> ;; BUG / FEATURE
> ;;
> ;; When declaring a c structure using define-cstruct
> ;; ctype-sizeof reports more bytes than was asked for
> ;; in the declaration.
> ;;
> ;; This bug is illustrated by the code and results below.
> ;;
> ;; The response I expect to this bug report is that it is in fact
> ;; a feature as opposed to a bug.
> ;;
> ;; To save an iteration on the Q & A loop.
> ;; I'm going to anticipate that response and reply to it:
> ;;
> ;; Whether or not a structure is implicitly padded may not be in the
> ;; control of the programmer developing the scheme interface to a C
> ;; library. Some structures will be padded others won't be so the
> ;; marshalling infrastructure has to expose control of padding and
> ;; alignment to the programmer defining an interface.
> ;;
> ;; In my opinion it is generally a mistake to hide such
> ;; behaviour because the programmer needs to be thinking about
> ;; the issue. Hiding it leads to mistakes.
> ;; It is desirable to leave the padding/alignment issue in the open.
> ;;
> ;; To be clear, individual interfaces can vary on the same O.S. on
> ;; the same hardware. C compiler features permit individual structures
> ;; to be padded or not as and when required.
Yes, that's all true, but there are certain rules about how to lay out
C data in structs which libffi uses -- and the foreign interface
basically exposes that at the Scheme level. Even more than that,
there is Scheme code that need to figure out the same numbers because
(AFAICT) libffi provides an interface to make new C struct types, but
no way to know their offsets -- so "collects/mzlib/foreign.ss" has a
function called `compute-offsets' which computes the offsets so it can
initialize such structs. So the only thing that is needed for things
to be as flexible as you want is for libffi to have a more generic
interface that allows me to create a new type where I specify its size
and alignment.
But this would only matter when you have structs that are substructs
or that are passed by value -- if the only way to move these things
around is by reference, then you can easily do so -- use an explicit
number of bytes to malloc, and set/ref things from the right offsets.
It won't be convenient, but it's possible.
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!