[2/5] msvcm80: Add stub dll.

Vincent Povirk madewokherd at gmail.com
Fri May 4 16:54:31 CDT 2012

I was sort of hoping for a reaction like this when I sent these
patches. I think this can work, and I figure given that it can we
might as well have it in Wine. I have a managed C++ hello world
program generated by visual studio working with some changes to mono
and the three msvcm stubs I sent.

The reason I started this is that I was blocked on making the native
msvcm work with Mono, and I didn't see a way of making anything
mixed-mode work without disassembling msvcm to see where it's going
wrong. But I think that in the process of making
mixedmodehelloworld.exe work I fixed the bug that was blocking native
msvcm, and I can go back to that.

> I imagine that he started working on this a while ago. Maybe he does have a plan for finishing this...

Haha, nope, I started it on Wednesday, and my plan is just to
implement/fix things as they turn out to be needed.

> msvcmrt? The Managed C++ Runtime DLL? I imagine you won't get far on that without a C++/CLI compiler that understands the Microsoft Visual C++ ABI--unless you're willing to write all the marshaling glue code by hand. There's only one such compiler right now, and it only runs on Windows. VC++ ABI support is on my Clang to-do list--heck, it's my GSoC project--but C++/CLI is something I won't get to for a while. Given all that, how do you intend to implement this?

The marshaling glue needs to be in Mono and mscoree, not msvcm. There
are two kinds of marshaling involved: P/Invokes, which are implemented
by Mono and call from CLR into native code (and some of which are a
sort of "internal" pinvoke that call a function inside the same PE
image, aka native code methods), and vtable fixups, which must be
implemented by mscoree and will call from native code into CLR. By
replacing msvcm with a builtin version, I was able to cheat a bit and
run hello world without implementing vtable fixups, but I'm sure they
will be needed soon.

As for doing native->CLR calls from within msvcm, there are a few
options, and I haven't chosen one yet:
* Build a managed helper that we can call on from msvcm. This is
problematic at the moment because we do not have a free compiler able
to create vtable fixups. They're not too complicated, so maybe we
could implement it in Mono.Cecil. Also, if we wanted to use this with
native .NET, we'd either need a way to ship CLR code with Wine.
* Use the mono embedding API to essentially build our own helpers
dynamically, or do what we need to do directly. This would not give us
a functional msvcm with native .NET.
* Use the .NET embedding API to do the same thing. This would give us
a functioning msvcm with native .NET, but it means we need to
implement the parts of the .NET embedding API that we need based on
Mono, which would be a sizable task.
* Detect whether builtin or native mscoree is being used and decide
which embedding API to use based on that. Since we only need the
embedding API to create CLR helpers and call CLR code that would be
the same either way, this may not be so bad.

I'd like to also note that, while native msvcm contains managed code,
it does not export any managed types, and mixed-mode assemblies do not
even import the msvcm assembly. I had previously believed that managed
exports would be required, but I now have the technology
(https://github.com/madewokherd/getclrinterface) to easily see that
they are not. Given that, it does not appear to be necessary for msvcm
to contain any managed code.

> int (__clrcall *handler)(struct _exception *)
> i.e. a "pointer to a function intended to be called from managed code that takes a pointer to a struct _exception and returns an int." The definition of struct _exception is in <math.h> under Visual Studio.

I would appreciate any information you can give me about how clrcall
is supposed to work. In spite of my ignorance of the specifics, I am
convinced that a call from native code to clrcall is possible without
a PE image containing CLR code.

> To write such a function, you'd need a C++/CLI compiler.

Is this kind of like how we need a C++ compiler for msvcrt?

In this case, we don't have to write such a function at all, we get it
from the caller. What we most likely need is a thunk that we can pass
to __setusermatherr that will call the CLR function.

I can think of a few possibilities for what clrcall might mean. If
it's some sort of object, such as a delegate, we should be able to
test that, and we can definitely call it.

Whatever it is, we also will have to make sure that Mono generates the
right kind of pointer. Given that Mono did attempt to call
__setusermatherr_m, and given that I made some changes to Mono that I
don't yet understand in order to make this work, Mono's current
behavior is either Mono's best guess at the right way to do this or a
random guess that I put in so I could move on.

More information about the wine-devel mailing list