[Mono-list] PInvoke Conventions

Jay Freeman (saurik) saurik@saurik.com
Sun, 29 Jul 2001 10:39:58 -0500


For people who don't read all of e-mail messages, at least skip to the end
of the semi-serious tag:

<semi-serious>
I see the answer is so obvious that it is eluding most people :).  You
aren't thinking 4th dimensionally:

The answer,   is MC++  .

Hehe.  Concentrate more time on figuring out how gcc works and get MC++
working.  Sure it will take a while, but if you add the time required to get
this terrible, terrible hack that is being proposing in place, and then the
time to rip it apart when something better comes along (or all the work that
is going to be required to get everyone else's runtimes in sync... currently
I'm going to have to agree with Rhys here until I hear more about how this
shared library would be constructed) and then multiply it by 2 (hey, gcc is
the garbage pile that all the other projects throw their bad code into, as a
fellow GNU project you have to be willing to go that extra distance when
required), you should have enough time to get a really crappy version of
MC++ operational.

Then all of the unmanaged types you use match up for free.  I'm pretty sure
that MS didn't write all of the managed code in the runtime libraries in C#
either (although, I admit, I doubt any of the foundation classes were
written in MC++ specifically).  Then again, gcc might be convoluted enough
that there is no hope, dooming the entire project... all about which risk to
take :-P.
</semi-serious>

How are the CLASSPATH people doing this?  From what I remember the JNI/CNI
code that they have is only what is _core_ to the platform (such things like
java_lang_thread.c) and things that other implementations are likely to
already have for themselves anyway.  You know wherever their ties to the OS
are they have to be through a wrapper accessible using JNI/CNI (as they
don't even have PInvoke); if the goal is to now do something through a
magical shared library you ar really ditching the whole PInvoke concept
(even if you use it in practice to make part of this work) and are dropping
down to emulating JNI/CNI/MC++ using a PInvoke abstraction (which, I agree
with Rhys, is closer to internalcall)... have someone should look at how
their wrappers are constructed as they now apply directly.

Really, that's an important point to stress, the current argument as to why
this is closer to internal call isn't strong enough.  Let's take this one in
reverse; not the strongest of methods, but you should hopefully find it
convincing:

Java does not have PInvoke, rather, it has the ability to call special
methods that are defined in a special way using JNI (or CNI if you are using
any of the open-source implementations as they didn't care as much as Sun
did about future garbage collection algorithms).  These methods can then use
native compiled code if need-be as they are, themselves, written in C.  This
is obviously not PInvoke, in practice or in concept.  It also isn't exactly
like "internalcall", as the functions themselves are user-developable
(internal call makes very, very close assumptions), defined separately, and
bound at runtime.  However, the idea is the same: having special methods
written that can themselves call native code because the caller can't do it
directly.  Now, let's say we changed the JNI classes into MC++ classes.
Here we have a rather cohesive philosophical fit: special code that can call
native methods that exposes a managed interface to the rest of the code to
use instead.

The only difference between this case and the shared library proposal is
that, instead of there being a managed interface being exposed by the middle
man (as is the case with JNI, CNI, and MC++), you are exposing something
that needs to be accessed using PInvoke.  Now, you are are, using PInvoke to
get access to a methodology that violates the concept of PInvoke.  The
actual managed code?  Nope, that still can't call native methods as no one
solved the root problem.  Here we have the case of special code (the shared
library) that can call native code that the managed version can't (as
cross-Unix compatibility is important to most people and PInvoke wouldn't be
capable of it).

Congratulations, you have just used a weakened crappy version of PInvoke to
"fix PInvoke" by not using PInvoke.  Anytime anyone wants to support a new
library, guess what, they are going to be in the same boat you are in: they
are going to have to write their own wrapper, distribute the wrapper with
their code, and use the wrapper using PInvoke, as PInvoke is incapable of
doing it directly.

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

----- Original Message -----
From: "Rhys Weatherley" <rweather@zip.com.au>
To: "Miguel de Icaza" <miguel@ximian.com>
Cc: <mono-list@ximian.com>
Sent: Sunday, July 29, 2001 1:15 AM
Subject: Re: [Mono-list] PInvoke Conventions


> Miguel de Icaza wrote:
>
> > > The trick is coming up with a *standard* way of doing
> > > this black magic.  I fear that if the "C wrapper" crowd
> > > wins this war, then the resulting C# library will only work
> > > with Mono's VM and the rest of us will have to start
> > > from scratch.
> >
> > I have to disagree with the conclussion Rhys.  [...]
> >
> > We are not advocating the use of internalcalls to solve the problem.
> > We will be using PInvoke, but wont be using any extra magic to label
> > the PInvoke methods: instead we will put the magic on a support shared
> > library (which we need anyways).
>
> And which will no doubt be hard-wired to Mono API
> and autoconf conventions, and hence useless to anyone
> else who may be interested in running applications built
> to work with the Mono C# library.  Hence, the rest of
> us will have to start from scratch.
>
> The proposal to use type diversion, where "stat" can be
> diverted to a "NativeStat" in a platform-specific assembly
> is much better than this.  The platform-specific parts are
> completely in a C#-based "native.dll" which is portable
> from one VM to another.  Any approach that uses C to
> make the glue will bind the C# library to one VM only.
>
> Rhys.