[Mono-list] PInvoke Conventions

Rhys Weatherley rweather@zip.com.au
Thu, 19 Jul 2001 11:37:18 +1000

Bob Salita wrote:

> I'd like to challenge your preference for libffi, so here goes. I'm unsure
> if I understand the functionality of libffi correctly, apologies in advance.
> 1. Doesn't every struct have to be defined in advance?

You have to build a descriptor for the struct, which is passed to
"libffi".  It then uses this descriptor to determine how to marshal
values.  I'm fairly confident that this descriptor can be built
at runtime from the metadata for the class.

> 2. Doesn't every call have to be defined in advance?

Same thing - you build a descriptor for the parameters and
then make the call.

> 3. Does it handle bit field endiness (left-to-right vs. right-to-left) which
> may differ between .Net and the C compiler.

No, it doesn't handle bit fields or unions.  But then, Microsoft
doesn't seem to handle them either.  There are no tokens
or attributes that I can find that change the width of an integer
to something less than the natural size.  I suspect that
structures with bit fields simply cannot be handled, and so
a wrapper function would be needed to handle them.

> 4. Is it a problem if the C compiler used to build mono handles structs
> differently than the C compiler used to build the lib?

The issue is the ABI, rather than the C compiler.  The ABI is
defined for each OS/CPU.  While ABI's for C++ vary quite
considerably, as Jay pointed out yesterday, the ABI's for C
are fairly well defined.  So, "libffi" shouldn't have any problems
with this.

There are no 100% guarantees here.  I seem to remember
some comments in the gcc backend documentation
that sometimes gcc uses different struct packing rules
than the "native" C compiler for parameter passing on
certain aberrant platforms.

But I think it is probably pretty safe to assume that most
of these aberrant C compilers have been flushed on Unix
systems by now.  Gcc has killed most of them off, and
the few remaining pockets of resistance are dying. :-)

> 5. Does it handle struct members that are assigned offsets in a
> non-ascending order (perhaps reversed)?

No idea.  I haven't gotten that deep into the "libffi" code yet.
See the aside below.

> 6. If definitions are required (1 and 2 above), then is it any better than
> using class wrappers?

1 and 2 really aren't an issue, as the necessary information can
be determined at runtime.

Aside: I doubt that we'll be able to handle every possible way
that C functions and struct's work.  However, I believe we can
get enough that the rest can be handled by requiring the
programmer to wrap the underlying API a little in C before
exported via a PInvoke.  No mechanism can be 100%, because
we are dealing with 30 years of accumulated cruft.