[Mono-dev] Mixed Mode Assemblies

Quandary quandary82 at hailmail.net
Sat Jul 9 06:20:45 EDT 2011

It's true that p/Invoke + InterOp services do not form a complete solution.
However, creating a interface in managed code across platforms isn't
very difficult.

All you need to do is to pack a x86&x64&ARM&PPC Linux&Windows&Mac
version of the native dll into the .NET dll's ressources, then stream
the respective assembly out on the calling of the constructor, and
create an abstract class, where you create an instance for the
respective platform (for example because of structs, where on x64, there
are different sizes of long + int on Windows & Linux/UNIX), which you
can then invoke as an interface.

However, if you write mixed-mode assemblies, those problems won't
automatically go away.
You'll have the advantage that you can use native datatypes, so the
compiler takes care of for example of the size of the C++ datatypes, not
to mention handle union's correctly, but then, at some point, it will
have to cast the received datatype from .NET to the respective native
datatype automatically, which can result in malfunctions due to the loss
of data on only some platforms or processors.

The bottom line is, if you use native code, it's gonna be native code,
and there is no way you can write it ONCE and run it everywhere, because
that simply doesn't work, certainly not in general, and most-likely also
not with restrictions to generality either - unless you reduce the
native code to basics like printf, in which case the usage of native
code would be pointless. And since printf is a good example of pointer
usage, even that might not work in the more complex usage scenarios.

And I would even dare to say that, in my opinion, it's likely that some
mixed-modes assemblies already fail when they go from Win32 to Win64,
that is - NOT even considering ONE different operating system with a
different C/C++ compiler. Not to mention that one can use a different
compilers for the same operating system.

If you want to write an assembly once, and then run it everywhere, it
must be a managed one, and there must be a runtime/VM that safely
handles types and datatypes for each platform (and make no mistake, even
then mono isn't guaranteed to be flawless).

If you use any form of non-managed API, that will break cross-platform
compatibility almost immediately.

And even if your interface is flawless, there still is another thing
that can go wrong:
Most people use int and long, they don't use int32_t or int64_t, which
means nothing else than that the native code can also break on its own
when ported to a different platform/processor. Not to mention all the
other little details that can change with a different processor
architecture (details of the calling conventions for example).

Then, you can also write code in C++, where the name-mangling isn't
standardised even across compilers on the same operating system with the
same processor, which will generate one hell of a mess.

On 07/08/2011 07:57 PM, Alex Corrado wrote:
> poster said:
>>>> >>> Without a doubt, every case where I've wanted/needed to use C++.NET has been
>>>> >>> to create a mixed mode assembly with the intent of creating a clean,
>>>> >>> optimized .NET interface for some piece of unmanaged code. If P/Invoke and
>>>> >>> System.Runtime.InteropServices formed a complete solution for importing
>>>> >>> native functionality into .NET, then I doubt Microsoft would have bothered
>>>> >>> allowing for mixed-mode assemblies at all.

More information about the Mono-devel-list mailing list