Runtime: Support mixed-mode assemblies on Windows

Created on 16 May 2018  ·  107Comments  ·  Source: dotnet/runtime

This issue will track progress toward supporting loading and running mixed-mode assemblies on CoreCLR. The main goal is to provide support for WPF and other existing C++/CLI code on .NET Core. Some of the work will be dependent on updates to the MSVC compiler.

Steps include:

  • [x] Documenting how mixed-mode assemblies work in general
  • [x] Proposing a .NET Core design
  • [x] Loading mixed-mode assemblies into running managed code
  • [x] Starting the runtime from native code in mixed-mode assemblies

This is related to dotnet/runtime#4116, but cross-platform support is outside of the scope of this issue as it's a compiler feature, not a runtime feature.

area-Interop-coreclr os-windows

Most helpful comment

Paint.NET author here ... you've got my attention :D I have 50 KLOCs of C++/CLI code ... let me know if you need a guinea pig :)

All 107 comments

Paint.NET author here ... you've got my attention :D I have 50 KLOCs of C++/CLI code ... let me know if you need a guinea pig :)

Thanks, @rickbrew. It'll be a while until we're ready for Paint.NET, but we'll keep you in mind.

I think we can start by reverting https://github.com/dotnet/coreclr/commit/1aa7d6b8796f7e28a63162117c5bb16a207a472b to at least allow the ability to load multi module assemblies.

@mjsabby, multi-module assemblies are orthogonal to mixed-mode. (Multi-module means you linked together netmodules using alink.exe, mixed mode means you have a combination of managed and native code in the same assembly). If you have a requirement for multi-module assemblies, I'd suggest filing a separate issue outlining what you need.

@morganbr Thanks. I'm not sure why I concluded that C++/CLI needs netmodule support.

Awesome we're making progress on this ground. C++/CLI is what we use to bridge native service to the awesome .NET world. So far no other alternative achieves the elegance of C++/CLI as a glue language so it's fair to say that we're going to rely on C++/CLI as an integral part of our service.

Some time ago in the spirit of searching for performance gains by migrating from .NET framework to .NET core I sadly found that .NETCore doesn't go together with C++/CLI (even though we don't care about cross-platform yet).

And now this thread lifts my mood 👍 Looking forward to the release (as while I searched for solutions I saw a lot of people had the same need with C++/CLI in their own projects)

@morganbr given that "Loading mixed-mode assemblies into running managed code" is done, should it be possible to use latest .NET Core 3.0 preview together with mixed mode assemblies on Windows? E.g. from a C# application?

We intent to use .NET Core 3.0 with WPF and have quite a lot of C++/CLI dependencies/libraries (a lot third party too), so looking forward to this.

@nietras, I'm glad to hear you're eager to give this a shot. It's probably a little early to try it with the latest preview though. While the runtime can run mixed-mode assemblies now, the C++ compiler also needs some changes to make everything work smoothly.

In case anyone's interested in details, the main C++ compiler changes are:

  1. Be able to build against .NET Core assemblies instead of .NET Framework (this isn't strictly blocking, but can cause issues if the assembly references a type that isn't in Core or wants to use a type that isn't' in Framework)
  2. An assembly built with the current release of the C++ compiler will load and call into mscoree.dll on startup, which starts up .NET Framework. As you might imagine, having both runtimes think they loaded the assembly can cause lots of problems.

@morganbr will the changes to C++(CLI) compiler that supports .NETCore be released together with the next version of Visual Studio, or will it be released out-of-band?

@pongba, I don't think we're ready to say exactly when or how we'll first distribute that version of the compiler, but it will eventually get distributed with Visual Studio.

So should it be possible to load assemblies which have ddlexports (vtfixup etc.) in them with the current preview of .net core 3.0? I am asking this because i just get a BadImageFormat exception when trying to load such assembly which i compiled with .net core 3.0 and used ildasm and ilasm to add the exports. The same code works when compiling with .net 4.6.2. I can provide the il code if required as a repro.

Considering of C++/WinRT, is it possible to write a standard C++ projection for .NET Core?

@morganbr Would be nice to get a response from you. Not being able to at least load assemblies which contain an dll export prevents me from porting https://github.com/cplotts/snoopwpf to .NET core 3.0.

@batzen, you could be hitting a few different issues. You might be able to narrow them a bit by seeing if directly calling LoadLibrary on your assembly in the .NET Core process works. Some possible issues:

  1. Processor architecture mismatch (in particular, .NET Core is x64 by default while .NET Framework is x86 by default)
  2. Depending on how exactly your imports/exports are set up, your assembly might be causing mscoree.dll to load. If that happens, it tries to start .NET Framework and all kinds of bad things (including BadImageFormat) can happen. You should be able to spot mscoree.dll loading in a debugger if you have mixed-mode debugging enabled.
  3. Something specific to your ildasm/ilasm process. You'd need to debug further into the error to find out if there's something .NET Framework-specific that you're relying on.

@Berrysoft, .NET Core supports WinRT, although some of the features may only be available in UWP applications.

@morganbr Oh, no, I mean, the current grammar of C++/CLI is non-standard. It is possible to make a projection of .NET Core with standard C++ grammar, so that other standard C++ compilers will compile the code, just like what C++/WinRT did for WinRT?

@morganbr

  1. Architecture is ok. Tried both, x86 and x64.
  2. It's a pure .net core 3.0 assembly. No reference to mscoree. Just one method in one class. IL code can be found at https://gist.github.com/batzen/8b1ed3e7269b4aaaacee846f188ef347
  3. I just run ilasm ManagedCore.il /outfile=ManagedCoreExported.dll /dll on the IL code from the gist.

Doing exactly the same for the equivalent IL code for .NET framework, which then of course contains mscoree references, works without an BadImageFormatException.
Loading of the modified assembly is done via Assembly.LoadFile.

If mixed mode assembly loading is supported in .NET core 3.0 are there any samples available? Some UnitTests you can point me to?

As this issue is assigned now, i guess you were able to reproduce it?

@batzen Mixed mode assemblies aren't supported in .NET Core 3.0 yet. This issue is tracking that support. @jkoritzinsky is actively working on investigating what needs to happen and the changes that will need to be introduced. Look for a design doc on this in the next week or two.

@AaronRobinsonMSFT if loading mixed mode assemblies not currently not support the task point "Loading mixed-mode assemblies into running managed code" in this issue should be unchecked, shouldn't it?

@batzen We support loading mixed-mode assemblies into running managed code with some specific workarounds to avoid accidentally loading .NET Framework into the process. The runtime work is already complete for that feature.

We're still working on starting the runtime when a mixed-mode assembly is loaded from native code instead of managed code and starting the runtime if needed. Additionally, there's some compiler work needed to have the Visual C++ compiler link against something other than .NET Framework's mscoree.dll for loading the runtime.

Support for setting up the vtfixup table in a non-mixed mode assembly is something else that I think is the base problem of your isssue.

Is there a sample somewhere on how to set up a mixed mode assembly for dotnet core 3.0 and how to load that into a running managed application?

//Ove

On my phone


From: Jeremy Koritzinsky notifications@github.com
Sent: Monday, February 4, 2019 22:38
To: dotnet/coreclr
Cc: ovebastiansen; Manual
Subject: Re: [dotnet/coreclr] Support mixed-mode assemblies (#18013)

@batzenhttps://eur04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fbatzen&data=02%7C01%7C%7C014210d3b7f34fdd9b3e08d68ae91c40%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636849131130015110&sdata=lF30W2mA8AdheQqc30GIRdf5uAxNX%2B0wBN5gLX33ZaQ%3D&reserved=0 We support loading mixed-mode assemblies into running managed code with some specific workarounds to avoid accidentally loading .NET Framework into the process. The runtime work is already complete for that feature.

We're still working on starting the runtime when a mixed-mode assembly is loaded from native code instead of managed code and starting the runtime if needed. Additionally, there's some compiler work needed to have the Visual C++ compiler link against something other than .NET Framework's mscoree.dll for loading the runtime.

Support for setting up the vtfixup table in a non-mixed mode assembly is something else that I think is the base problem of your isssue.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHubhttps://eur04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdotnet%2Fcoreclr%2Fissues%2F18013%23issuecomment-460422911&data=02%7C01%7C%7C014210d3b7f34fdd9b3e08d68ae91c40%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636849131130025114&sdata=hpgDfah2UN5vjCgi84BWB7BhxqggitHhvwB78%2Bnl%2FQM%3D&reserved=0, or mute the threadhttps://eur04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAQSuAeLAM3EyGvUwgCMu8BnkzuyhtDTFks5vKKhXgaJpZM4UAdnr&data=02%7C01%7C%7C014210d3b7f34fdd9b3e08d68ae91c40%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636849131130025114&sdata=gcW6PgaOqzl6NVHQLRFP51azZHHDiQ6Y0igINNmbrFk%3D&reserved=0.

Hi.
Any progress with the ability to create c++/cli assembly and load it into my .Net core app?
Is it planned for. Net core 3.0 release?

@meirkr There is good progress. See https://github.com/dotnet/coreclr/pull/22636 and https://github.com/dotnet/core-setup/pull/5185. Much of what we are waiting on is VC++ tooling support. The plan is for the .NET Core 3.0 release.

The runtime/hosting work for C++/CLI has been merged in. We're just waiting on the VC++ compiler/tooling support now before we can validate the end-to-end experience.

@jkoritzinsky, will the new VC++ compiler targeting .Net core be able to compile old c++ runtime (vc10 for example) ?
Thanks

hope we can test this with preview 4

@ghbeta we are already at VS 16.0 preview 5 ... so I don't know what you mean with preview 4 ;-)

From what it looks like you probably can expect something for VS 16.1 preview 2, at least the comment in the WPF repository indicates thats their current plan (which of course could change if things go badly, so don't take it as officially announced)

@fabricefou I am not sure if it will be able to target old runtimes. I don't believe it will be able to target anything lower than the VS2019 MSVC++ compiler can currently target.

1.
How can it be tracked?
Is there a target date already?

2.
Is there a temporary workaroind to configure something manually?
I guess this activity here have used some solution to develop and test this capability. Haven't it?

@ghbeta we are already at VS 16.0 preview 5 ... so I don't know what you mean with preview 4 ;-)

From what it looks like you probably can expect something for VS 16.1 preview 2, at least the comment in the WPF repository indicates thats their current plan (which of course could change if things go badly, so don't take it as officially announced)

i was meant .net core preview 4. just noticed the vs16.1 preview 1 is arrived, hope the c++ compiler will be ready at preview 2, i assume we have to retarget the framework of cli c++ project to .net core 3.0?

Will we also be able to share a C++CLI dll between .NET Core and Framework?
We would like to avoid producing two dlls, one for each case.
Is there a recommended way to do that?

@gpetrou Unfortunately it is unlikely that will be possible. C++/CLI binaries targeting .NET Framework will have mscoree.dll as the embedded host entry point. For .NET Core, a different host binary will be used - ijwhost.

Thanks for the quick reply.
If we do have to produce two C++/CLI dlls, can we at least avoid producing two dlls that reference them?
We would like to use a .NET Standard dll that references the C++/CLI dll (only on Windows). This .NET Standard dll in turn, can be referenced by other .NET Core or .NET Framework assemblies.
So, can we somehow inside the .NET Standard dll decide which C++/CLI dll we need to load?

@morganbr @Berrysoft I too would favor an ISO C++ language projection to use on Linux machines with either Clang or GCC and on Windows with Clang or MSVC. Wrapping native libraries for speed and wrap them with .Net goodness would rock. I typically run HPC code but there are times I'd wrap them with .Net and use some other language to call them for convenience. C++/CLI is a nice gluing material, but it's not portable and ISO C++ is moving rapidly, so the extensions are starting to show age.

What's the status on using C++/CLI? 16.1 preview 2 went live and apparently WPF is now using the new compiler in dotnet/wpf#640, but nothing was in the release notes explaining how to use it yourself.

I'd like experimenting with C++/CLI in .NET Core, what do I have to do to enable it?

@weltkante

I believe the most recent information is in https://github.com/dotnet/wpf/issues/607:

Many of you are probably aware that there is currently no support for building C++/CLI in .NET Core. In Dev16.0 (aka Visual Studio 2019), the C++ team has added limited capability (note: I didn’t write “support”) for compiling C++/CLI assemblies targeting .NET Core. For more details on how this works in the WPF codebase, please dig into Wpf.Cpp.props/Wpf.Cpp.targets and search for /clr:netcore. (If you try to use this today, it will probably not work for you due to a bug – please wait until Visual Studio 2019 Preview 2 comes out).

This limited support for C++/CLI has no SDK support yet. In other words, we couldn’t just take a C++/CLI vcxproj project that targeted .NET Framework and retarget it to .NET Core – the underlying NuGet support for discovering .NET Core references and a myriad of other build targets just didn’t exist. We worked with several colleagues in the .NET and C++ teams to build our own limited support for discovering the right NuGet references during build (see CppCliHelper in Wpf.Cpp.targets)

As you noted, VS 16.1 preview 2 is now out, so presumably that bug should now be fixed.

I'm a bit confused as to where this is all heading. Currently in VS 16.1 Preview 3.0 I create a C++ project. I can then switch on /clr in the properties and select a .NET target framework say v4.7. These are "old" style names like "v4.7" not new SDK ones like "net47". At some point will I be able to type "netcoreapp3.0" and things will just work? If so will the .vcxproj file remain roughly the same as now or will it change to "SDK" style?

You can set the /clr to netcore already, but be aware that its very early preview, the WPF repository is configuring the project in props/targets files and applying various other configurations because there is no .NET Core project template for C++/CLI yet so everything needs to be set explicitely. I didn't have the time to get it running myself yet, but it looks like everything is there if you want to try for yourself.

I don't think the project format will change to "SDK" style, from looking at the modifications it can all be done in the existing project system.

I don't understand how shall I try it.
This is the current command line generated by the CLR class library template.
How to configure it to point to .net core/standard instead of 4.7.2?

/Yu"pch.h" /GS /analyze- /W3 /Zc:wchar_t /Zi /Od /Fd"Debugvc142.pdb" /Zc:inline /fp:precise /D "WIN32" /D "_DEBUG" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Oy- /clr /FU"C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.7.2mscorlib.dll" /FU"C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.7.2System.Data.dll" /FU"C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.7.2System.dll" /FU"C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.7.2System.Xml.dll" /MDd /FC /Fa"Debug" /EHa /nologo /Fo"Debug" /Fp"DebugCoreClrCpp.pch" /diagnostics:column

@meirkr It doesn't work out of the box yet, it requires a lot of workarounds (that's probably why they didn't even bother to mention it in the VS preview notes that its possible to use C++/CLI). If you know how to read the props/targets of a vcxproj you can look at the WPF project (link in my other answer above) to see what workarounds are needed. Otherwise it's probably best to wait until they can finish proper integration into VS without tons of workarounds.

can you share an empty project file which has that tweek?
It could be a reference to a project file.

@meirkr sorry no, as said above I didn't have time to get it running myself yet

Also its not just a simple tweak either, for example the build has to configure the C/C++ runtime and also resolve (or hardcode) all managed assembly references manually, which is quite a big workaround to implement. The WPF project file creates a dummy project and parses the results to resolve packages. (I'd probably just hardcode the references for now though, if I were to experiment with it)

Either way, I don't think you can use this by simply tweaking the project file itself yet, you need to have these workarounds which run during the build process. So if you don't understand how it works its probably too early to try it out. (I do understand most of the props/targets used in the linked files but currently don't have the time to reimplement all the workarounds in a standalone project. If I find the time to set up a sample project before VS gets proper integration I'll drop a note here.)

Hitting this myself porting a 4.7.1 WPF app to .NET Core 3 - very much looking forward to this working out of the box (even if there are quirks).

Update: The feature work on the .NET runtime side is complete. I've marked the issue as blocked as the full scenario isn't yet complete due to the work on the C++ side still being in-progress.

@jkoritzinsky
Thanks for the update - I guess I will hold off the .NET Core 3 porting effort.

@jkoritzinsky please provide if there is a plan to support mixed-mode assemblies in both Windows and Linux environment under .NET Core 3. Which issues we can follow the progress

@GeorgeS2019 As far as I know there are no plans for mixed mode assemblies on Linux, there exists no working language equivalent to C++/CLI on Linux so there is not much point in providing the mixed mode capabilities. The current efforts are purely for getting certain Windows interop scenarios running when porting from Desktop Framework to .NET Core. I think you are supposed to use P/Invoke & co if you develop new code and need to interact with native code on Linux.

There are no issues known to me for following Linux mixed mode progress because nothing is planned (i.e. there will be no progress). If you are interested in C++/CLI specifically there is dotnet/runtime#4116 still open but without external contributions probably not going anywhere anytime soon.

@weltkante C++/CLI compiled on Windows for .NET works on Mono just fine, even on Linux, provided you use /clr:safe: https://www.mono-project.com/docs/about-mono/languages/cplusplus/

Not sure if this is what you meant by "working language equivalent" but it seems worth mentioning.

@SwooshyCueb The question was explicitely about mixed mode assemblies (not C++/CLI compiling to managed IL). To produce mixed mode assemblies you currently need a C++/CLI compiler, as there are no other languages producing mixed mode assemblies. Sure, you can configure C++/CLI to compile its input down to IL not containing native code, but then you didn't produce a mixed mode assembly in the first place.

@GeorgeS2019 The support represented by this issue is related to Windows only. There is presently no plan to support mixed mode on any non-Windows platform. Issues related to non-Windows support is at https://github.com/dotnet/coreclr/issues/659.

C++/CLI compiled on Windows for .NET works on Mono just fine, even on Linux, provided you use /clr:safe

@SwooshyCueb Definitely worth mentioning and requesting that clarity. The various flags that can be provided with the /clr flag make talking about this scenario require an increased level of precision in our communication. As @weltkante mentioned, this issue is specifically for mixed mode which by definition implies both managed and native code within the same assembly.

@jkoritzinsky For .NET Core 3.0, we should specifically call out which arguments to the /clr flag are supported.

@AaronRobinsonMSFT If I understand correctly, one key difference between .NETCore 3.0 and .NET5 is that the support for mixed-mode assemblies for non-windows will happen in .NET 5, unless MS decide to abandon C++/CLI for non-windows.

It is important for the community to know that the mixed-mode assemblies for non-Windows IS CONFIRMED for .NET 5 with an estimated timeline for the preview version.

one key difference between .NETCore 3.0 and .NET5 is that the support for mixed-mode assemblies for non-windows will happen in .NET 5, unless MS decide to abandon C++/CLI for non-windows.

@GeorgeS2019 I don't think that has been implied at all. The official .NET5 plan was announced here and C++/CLI isn't mentioned all, was there another post that mentioned this? At present, there is no plan to support C++/CLI on non-Windows. One of the biggest reasons is compiler support off Windows. We are tracking this request in issue https://github.com/dotnet/coreclr/issues/659 and will update that if official plans change.

I'm following this thread because I was/am interested in being able to wrap native code with .Net to be consumed in PowerShell. I think it is far more likely to get a C++/WinRT-ish auxiliary compiler, which is able to generate ISO C++ header files from .Net assemblies, and a matching template library that is able to generate code for consuming native types from .Net code. This approach could be pursued with Clang and GCC as well.

Kenny Kerr was asked about this once, and he said that the ABI of .Net is a lot more trickier than the COM-inspired WinRT is. To be honest, C++/CLI does start to show its age compared to C++17/20, and a helper compiler does seem to make more sense. _(With reflection and std::embed on the way, all of the extra machinery could even be done inside an ISO C++ compiler as well, but that's just wishful thinking.)_

As a rule: Most of what C++/CLI does can be done with just P/Invoke. The biggest that cannot is merging the two assemblies into one.

If you want a tool to help you:

  • If you simply want to call C++ code from .NET, SWIG is your best bet.
  • To go the other way, look at .NET Embedding

@SamuelEnglard Sure but a great thing about C++/CLI is that you can stack the dependencies. I have a C# "base" DLL that my C++/CLI DLL uses, and then more C# DLLs on top of the native one. This allows me to have common primitives (e.g. Point2Int32, RectInt32, whatever) and utility classes shared across the whole system, instead of having to duplicate and mix things around.

@rickbrew C++/CLI is great, the key is that what it's doing can be done without it, doing so is just a major pain. As you note you'd have to manually create types in both C++ and C#.

The work necessary to complete this issue is now tracked internally on the Microsoft C++ compiler. I am going to close this issue for now as all known work has been completed in dotnet/coreclr.

@jeffschwMSFT : Is there any publicly-trackable issue from the C++ compiler? If not, how will we know when we can / should try this out?

The C++/CLI compiler and project system work is aligning with the Visual Studio 2019 schedule. Adding @tgani-msft to help with timing questions.

@jeffschwMSFT thanks! Timing would be great to time a future release.

Our stated goal has been to release along with .NET Core 3 (likely runtime and compiler support). I will chat with @tgani-msft to see if that has changed.

Will C++/CLI code also be compatible with Linux in .NET Core 3 ?

@chriss2401 There's a branch of gcc that can do this, I think

@chriss2401 There's a branch of gcc that can do this, I think

Thanks for the reply. So theoretically it should be possible to run on Linux just by adding "netcoreapp30" (when it is released) to the target framework(s) ? Maybe @jeffschwMSFT has an idea about this ?

@SwooshyCueb you might be mixing up C++/CLI vs. mixed mode assemblies. They are not the same, mixed mode assemblies are a technology while C++/CLI is a language (though currently the only one which can output mixed mode assemblies). While gcc once had an experimental branch for C++/CLI it probably doesn't support mixed mode, which is tightly bound to the runtime it is compiled against.

@chriss2401 no it won't just work, there was no work done to support loading mixed mode assemblies on Linux. (There's not much point to implement a loader if there is no language which can generate code for it. Which means the language and runtime need to be kinda co-developed in order for mixed mode to ever arrive on Linux.)

Support for C++/CLI on Linux is discussed in dotnet/runtime#4116

@weltkante My bad, I misread "compatible" as "compilable" in @chriss2401's comment. And I think you're right about the gcc branch not supporting mixed mode.

Our stated goal has been to release along with .NET Core 3 (likely runtime and compiler support). I will chat with @tgani-msft to see if that has changed.

@jeffschwMSFT Any update on this?

@jeffschwMSFT also still waiting on this feature to complete my porting efforts to .NET Core 3. Any date other than the September release?

@jgoyvaerts @jcapellman Sorry for the delay on the response. An official blog about this issue is in the works and once published with be linked here.

Great thanks @AaronRobinsonMSFT!

@AaronRobinsonMSFT Any update on this?

Adding @tgani-msft. @AaronRobinsonMSFT and our team have completed the runtime/libraries portion of this work. @tgani-msft and the C++ compiler/tooling team are working through the scheduling details of when they will ship this scenario.

@jeffschwMSFT thank you for the update - crossing my fingers it can come next month.

continue waiting
.net core 3.1(/VS16.4) at november 2019

https://devblogs.microsoft.com/dotnet/announcing-net-core-3-0-preview-9/

Livar Cunha 2019-09-06 18:50:23

Tadeas Lejsek: Can you please include details about C++/CLI suppo...

That's coming in .NET Core 3.1 and VS 16.4

FYI: releated document updating plan.
https://github.com/dotnet/docs/issues/13152

@eightcloud83 - Q1 update of my product will have it then. Thanks for posting the response here.

I want to share a quick update on this. The latest on the C++/CLI roadmap can be found on our C++ blog here: https://devblogs.microsoft.com/cppblog/the-future-of-cpp-cli-and-dotnet-core-3/

.NET Core support for C++/CLI is coming in .NET Core 3.1 which is shipping with Visual Studio 2019 16.4.

I want to share a quick update on this. The latest on the C++/CLI roadmap can be found on our C++ blog here: https://devblogs.microsoft.com/cppblog/the-future-of-cpp-cli-and-dotnet-core-3/

.NET Core support for C++/CLI is coming in .NET Core 3.1 which is shipping with Visual Studio 2019 16.4.

Awesome news! I have to admit the minute I saw the 16.4 Preview 1 become available I downloaded to recompile my C++/CLI component that has been keeping me in .NET 4.8.

I cannot find options to create project using C++/CLI with .net Core with 16.4 Preview 1..
Seems need to wait 16.4 Preview 2,3...

Replied @ https://devblogs.microsoft.com/cppblog/the-future-of-cpp-cli-and-dotnet-core-3/
Will Buik September 25, 2019 9:57 pm
We are still working on the IDE and MSBuild integration, so I can’t share a sample project quite yet. Once it’s available, likely with 16.4 Preview 2 or 3, we will post an update on the blog.

16.4 Preview 2 released.

10/15/2019
https://docs.microsoft.com/en-US/visualstudio/releases/2019/release-notes-preview#16.4.0-pre.2.0

  • C++/CLI now supports interop with .NET Core 3.1 and higher on Windows.
  • Fixed an issue where building C++/CLI apps targeting 3.1 .NET Core breaks.

16.4 Preview 2 released.

10/15/2019
https://docs.microsoft.com/en-US/visualstudio/releases/2019/release-notes-preview#16.4.0-pre.2.0

16.4 Preview.2,
I'v tried to new "CLR Class Library (.NetCore)", "c++ library target the .net Core",
and new ASP.Net Core 3 project, try to call c++/cli function from asp.net core web,
Build succeeds with warning..

Yes!!!
It works if platform target set to "x64" when useing iis expess (@x64 windows).
( asp.net core, c++/cli dll, iis express need to be same plateform)

(
(VS debug setting can set IIS Express Bitness, default @x64 windows should be 64,
so if asp.net core plateform, c++/cli dll set x86 will...)
If platform target set to "x86",
"
HTTP Error 500.0 - ANCM In-Process Handler Load Failure
"
)

There are a few known issues in the preview. One is that you need to make sure the projects' architectures all match up between the C++/CLI class library and the .NET or ASP.NET Core application that consumes it. So all projects must be Win32/x86 or all x64. Make sure none of the .NET Core projects are set to use "Any CPU" in the Configuration Manager.

For ASP.NET Core there is an additional requirement that they must also match the architecture of IIS Express - which is usually x64. Otherwise the entire website fails to load with "500.0 - ANCM In-Process Handler Load Failure."

We are looking into ways to make this smoother, but hopefully this can work around the issue.

I want to try this out but I'm getting

1>C:Program Filesdotnetsdk5.0.100-alpha1-014915SdksMicrosoft.NET.SdktargetsMicrosoft.NET.Sdk.FrameworkReferenceResolution.targets(282,5): error NETSDK1073: The FrameworkReference 'Microsoft.NETCore.App' was not recognized

  • I have the latest VS preview update
  • the project is set to netcoreapp3.1 (by default, but verified it anyways, project file has <TargetFramework>netcoreapp3.1</TargetFramework>)
  • I have the latest dotnet 5 nightly just to make sure I'm not running into any already fixed bugs

any way to prevent VS picking up the wrong SDK?

That is an issue with the 5.0 SDK builds at this point. They don't support targeting netcoreapp3.1. I suggest uninstalling that and using the 3.1.100-preview SDK that comes with VS.

5.0 is in very early days and the branches are not in great shape right now.

Hu, there's no way to tell VS which SDK to use? Oh well, thanks for the info. I start seeing a pattern now, there was another issue where I was getting bits from the wrong 3.0 preview when I had the 5.0 SDK installed. Makes me wonder why it bothers installing side-by-side if it doesn't work side-by-side. I hope the experience can be improved in the future, downtimes of several months during releases are annoying. I'll have to live with regular uninstall/reinstall cycles for now I guess (I'm sometimes testing fixes which only go into 5.0 branches)

Sorry, you can tell VS to use a specific SDK using global.json.

oh, thanks, I'll try that out then!

.net core 3.1(/VS16.4) at november 2019

.net core 3.1 has been set to december 2019. (so as VS16.4?)
(c++/cli .net core works on .net core 3.1 preview1 and VS16.4 preview2 (or VS16.3 with modifed proj setting ) )

Does this mean we can run existing C++/CLI assemblies in .NET Core apps without recompiling them?

Does this mean we can run existing C++/CLI assemblies in .NET Core apps without recompiling them?

Existing C++/CLI assemblies are hardcoded to initialize .NET Framework, as such they need to be recompiled against .NET Core to function properly.

Does this mean we can run existing C++/CLI assemblies in .NET Core apps without recompiling them?

Well, I've tried a few existing C++/CLI assemblies compiled with .NET Framework, and they run successfully even on .NET Core 3.0, but I strongly suggest recompiling them. I think they could run on .NET Core because of the compatible mode of .NET Core, but it doesn't ensure the success.

Existing C++/CLI assemblies are hardcoded to initialize .NET Framework, as such they need to be recompiled against .NET Core to function properly.

Ach, that's really disappointing :cry:

We use some 3rd party mixed-mode assemblies which are the only thing tying us to the .NET Framework, and the chance of the vendor recompiling is close to zero.

No chance of some kind of compatibility layer then?

No chance of some kind of compatibility layer then?

API wise they are likely close to compatible. The challenge is around activation. If the assembly believes it needs to activate .NET Framework there is very little we can do.

@jeffschwMSFT what if .NET Core is initialized by the caller? Would the mixed assembly just use what's already loaded?

what if .NET Core is initialized by the caller? Would the mixed assembly just use what's already loaded?

The C++/CLI activation rules are complicated. Having .NET Core initialized is not sufficient. The rules can generally be distilled down to - if assembly's dllmain determines that the runtime needs to be activated, it will activate .NET Framework. There is not a reliable way to ensure that.

For testing purposes we have provided a shim for mscoree to intercept these calls, but that is not something that we would recommend as a durable solution.

Is this only a problem if unmanaged exports are being used, or will DllMain be hit during managed load? In other words if I understand the process correctly will the native import which causes mscoree to load chain back to the native entry point?

Second question if this is a WPF or desktop app will someone start calling the DLL from native code?

My thought is that if C++/CLI is being used for native needs internal to the app and native pinvokeimpl methods are only called from IL then DllMain might never run?

It is a combination of the OS and binary making these decisions. It is likely possible to model these and narrowly avoid the unintended loading of .NET Framework, but I would advise against it. Our recommendation is to rebuild with .NET Core - which avoids all of these issues.
You have the right direction on when it is possible for .NET Framework to be loaded (both in dllmain and the first time that p/invokes are executed).

Well if you don't have source code it'd be worth a try - first check would be to see if there are any native exports beyond what an empty project would create (a staggering lot, I warn you). Also if the time is still that men are made of steel and ships from wood as opposed to the other way around then you could figure out everything with dumpbin /DISASM and ildasm and/or IL Spy.

I just tried porting an old managed C++/CLI project, but I'm getting a BadImageFormat exception when I try to use it:

Unhandled exception. System.BadImageFormatException: Could not load file or assembly 'MyAssembly, Version=2019.0.1.0, Culture=neutral, PublicKeyToken=null'. An attempt was made to load a program with an incorrect format.
File name: 'MyAssembly, Version=2019.0.1.0, Culture=neutral, PublicKeyToken=null'
   at TestApp.Program.Main(String[] args)

Both the managed assembly and test app target X64, and I'm using Visual Studio Preview 16.4.0 Preview 4 with .NET Core 3.1 preview 2. The built assembly looks to be the correct size, and decompilers such as JustCompile or ildasm work with it just fine. I can see it has a TargetFrameworkAttribute set pointing to NETCoreApp,Version=v3.1.

Any ideas what could be the problem?

We use some 3rd party mixed-mode assemblies which are the only thing tying us to the .NET Framework, and the chance of the vendor recompiling is close to zero.

Just wanted to acknowledge that as with @cocowalla we are in the exact same position, we have mixed-mode assemblies from third parties that have no intention of updating to .NET Core, this basically ties us to a dead platform in the form of .NET Framework 4.8 and we are left (again) with stagnant technology. This is a problem. I love .NET Core and all the great things in it, but what use is it if we can't use it in key projects?

this basically ties us to a dead platform in the form of .NET Framework 4.8 and we are left (again) with stagnant technology

Stagnant fine but dead?

".NET Framework 4.8 will be the last major version of .NET Framework. If you have existing .NET Framework applications that you are maintaining, there is no need to move these applications to .NET Core. We will continue to both service and support .NET Framework, which includes bug–, reliability– and security fixes. It will continue to ship with Windows (much of Windows depends on .NET Framework) and we will continue to improve the tooling support for .NET in Visual Studio (Visual Studio is written on .NET Framework). " - .NET Core is the Future of .NET

Any ideas what could be the problem?

@cocowalla Mismatch between 32/64 bit? Are you sure you are running the .NET Core application in the same bitness as the C++/CLI library was compiled?

@cocowalla Mismatch between 32/64 bit? Are you sure you are running the .NET Core application in the same bitness as the C++/CLI library was compiled?

Nope, as I mentioned, both the managed assembly and test app target X64. I even confirmed with dumpbin /headers 😞

@cocowalla for new issues it likely makes sense to open new issues. In this case can you ensure that ijwhost.dll is present? For .NET Core to successfully activate C++/CLI this component is necessary. We are aware that the error message is not helpful, and are looking to improve that experience.
By default if you build with VS 16.4+ with a C++/CLI project this file is added automatically.

@jeffschwMSFT fair point, will open a new issue. Regarding ijwhost.dll tho, is this meant to be in the same dir as the app running the managed C++/CLI assembly?

ijwhost should be along side the C++/CLI assembly

@jeffschwMSFT brilliant, thanks!

The ijwhost.dll was indeed missing - it was output by the C++/CLI project, but wasn't in the output of the test app. Now it's there, it seems to work!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matty-hall picture matty-hall  ·  3Comments

omariom picture omariom  ·  3Comments

chunseoklee picture chunseoklee  ·  3Comments

jzabroski picture jzabroski  ·  3Comments

jchannon picture jchannon  ·  3Comments