[Mono-list] PInvoke Conventions

Jay Freeman (saurik) saurik@saurik.com
Wed, 18 Jul 2001 11:33:20 -0500


Sam:

That's the entire point of this thread.  In that case, instead of "int",
"long" would be used.  It is a matter of whether or not that change is going
to be done by entirely different sets of code that come with the runtime
(one for 32/32, one for 32/64, and one for 64/64, and one for whatever
else), or by some other means.

If you mean for end users who want to use PInvoke, I don't think anyone put
much thought into the circumstance that these poor fools will be placed
under :-).  My guess would be that they could either use the same system
developed for the runtime library itself (if one is), or would just have to
understand that each different bittage of architecture need be considered a
different platform.

Personally, I don't see anything wrong with adding a new attribute specific
to Mono to help with this scenario.  Of course, then the generic problem
that you have brought up applies, inside the library classes that use these
functions, are we going to be rounding?  It might turn out that, even if the
end result is rounded or converted into some more abstract notation for the
end user, it is inappropriate/inaccurate for the rounding to occur inside
the function.  This would require changing not only the PInvoke itself but
also the code that uses it.

Rhys mentions that Windows does not have this problem because the sizes of
parameters will stay the same on a 64-bit version of Windows, but I don't
really believe that.  32-bit Windows changed the sizes of everything from 16
to 32 bits, my bet would be that 64-bit Windows will make similar changes
(by upping the definition of WORD and DWORD).

To answer your question directly, however, if you were to use the definition
you mentioned on a 64-bit system, you are likely ok.  First, the string will
know to marshal itself to a C string with the correct number of bits for its
pointer.  Your only ambigous case is in the return value, which is almost
assuradely going to be returned in a register in that case (it won't on all
architectures, if it comes back on the stack you're screwed), and would be
whether it was returning 32 bits or 64 bits (as te 64-bit system should have
64 bit registers).  What you get back will be rounded.

However, if you tried to pull that with something like lseek (one of the
examples in Rhys's document), you wouldn't have any hope of _sending_
rounded (or simply being limited by what you thought it was when you set it
up) values, the call would simply be invalid.  The runtime needs to know the
arguments used to call the system command.  Seeing that the libraries that
we are calling export their functions with C naming conventions (where, as I
mentioned, just the name of the function is in the library, not what
arguments it takes or any extended information on the function), and that
the runtime does not have some master list of what arguments these functions
_should_ take, there is no way to know that system() _really_ returned 64
bits or that lseek() _really_ took one 32-bit, one 64-bit, and then another
32-bit integer.

Rather, the runtime relies on the developer who writes out the PInvoke to
make sure that all of his types will, in the end, marshal to right parameter
types so they can be pushed on the stack in the correct order.  If you only
specify 3 int's to this call, then you would be 32-bits short of a valid
lseek() call, and lseek() is going to use arguments that overlap with the
ones you intended in memory, in addition to part of the stack before the
arguments.

Sincerely,
Jay Freeman (saurik)
saurik@saurik.com

----- Original Message -----
From: "Sam Ruby" <rubys@us.ibm.com>
To: "Bob Salita" <bsalita@hotmail.com>
Cc: <rweather@zip.com.au>; <mono-list@ximian.com>
Sent: Wednesday, July 18, 2001 10:33 AM
Subject: Re: [Mono-list] PInvoke Conventions


> Bob Salita wrote:
> >
> > Sam, which conventions are you refering to? Please give an example of
the
> > target C call and the DllImport definition.
>
> [DllImport("libc")] int system(string command);
>
> How does this work on machines in which the "C" definition of "int" is 64
> bits?
>
> - Sam Ruby