Does Xamarin's Android for Mono support same .NET libraries as Mono? - mono

At a high level, my question is:
Is everything that is supported by Mono on a Linux platform supported by Android.Xamarin on an Android platform?
More information: I am investigating the possibility of porting a complex C# application which was targeting the .NET v3.5 framework onto an Android tablet, and want to confirm my understanding of what is supported in Mono vs what is supported on an Android device.
Mono's Compatibility list does a pretty great job of explaining what features are supported in the Mono architecture. As they so clearly state, mono supports:
Everything in .NET 4.0 except WPF, WWF, and with limited WCF.
However, understanding what is supported in Xamarin for Android is not as easy. I found this topic on Assemblies, which includes a description of the namespaces supported under System.dll
Silverlight, plus types from the following namespaces: [more listed]...
The silverlight reference mentions that System.Windows.Threading is under silverlight, but this doesnt seem to make sense if I simply create a new project.
Here's an example: if I open a new mono project and attempt to access System.Windows.Threading, I cannot access it unless I include a reference to WindowsBase.dll. Moreover, I can only successfully reference WindowsBase.dll from within an "Android Class Library" Project - if I attempt to create an "Android Application" Project and attempt to reference WindowsBase.dll I receive a cryptic compilation error, pasted below.
Error 2 Exception while loading assemblies: System.IO.FileNotFoundException: Could not load assembly 'WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. Perhaps it doesn't exist in the Mono for Android profile?
File name: 'WindowsBase.dll'
at Xamarin.Android.Tuner.DirectoryAssemblyResolver.Resolve(AssemblyNameReference reference, ReaderParameters parameters)
at Xamarin.Android.Tasks.ResolveAssemblies.AddAssemblyReferences(List`1 assemblies, AssemblyDefinition assembly)
at Xamarin.Android.Tasks.ResolveAssemblies.AddAssemblyReferences(List`1 assemblies, AssemblyDefinition assembly)
at Xamarin.Android.Tasks.ResolveAssemblies.Execute() C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets 720 2 AndoidCtmConnectionTester
So my follow up question is: Why would I get a compilation error when referencing a DLL from an Android Application project, but not an Android Class Library Project

System.Windows.Threading is considered as a part of WPF, so there no intention to make it work in Xamarin.Android.
If you want to reference .NET assembly directly, Xamarin.Android can load only few simple .NET assemblies (and with warning: "The referenced project is targeted to a different framework family (.NETFramework)" )
There is also a big chance that WindowsBase.dll is wrapping some win32 native methods, so it is impossible to run it under Android environment.
So the bad news is that you need to port your code to System.Threading classes.

Related

Migration .Net framework to .NET 6 - class library

During migration of our existing project targeting .NET framework 4.8 we encountered starnge error:
MC1000 Unknown build error, 'Could not find type 'System.Web.PreApplicationStartMethodAttribute' in assembly 'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.5\ref\net6.0\System.Web.dll'.'
error message image
Basically we have one big class library targeting net6.0-windows that has been used across multiple different smaller projects.
This class library is compileable as a stanalone porject with no errors, but as soon as we reference it in our WPF project, also targeting same net6.0-windows, we got this error.
Does anyone experiencing sme problem?
Any help appreciated...
Eventually I found that mixing of ASP.NET components together with WinForm or WPF is not allowed anymore. So solution was to split our library file into two separate DLL assemblies each targeting proper SDK.

.Net Framework 4.7 console app references .NET core dll - unexpected files in output directory

I have a .NET Framework Console app (.Net Framework 4.7) which references a .NET Core dll (.Net Standard 2.0). The .Net core dll uses nothing outside NETStandard.Library.
I noticed some unexpected files in the /bin/Debug directory. After some investigation I have determined that these are not coming from any of the referenced packages, but are being copied from
C:\Program Files (x86)\Microsoft Visual Studio\Preview\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\\net461\ref
The contents of this directory differ across the machines we are using, causing different DLLs to end up in the output directory. This was making the debugging process inconsistent.
Now that I have worked out what was causing the problem, I was wondering what the explanation of this is, and whether there is a way to prevent it from happening, ie to have only the packages referenced in the project be copied to /bin/Debug
These files are expected and even required to allow .NET Standard libraries to work on .NET Framework. They contain the necessary type forwarding definitions so that at runtime, every assembly can be loaded correctly - for example, libraries can reference System.Object from netstandard.dll (.NET Standard >= 2.0) or System.Runtime.dll (.NET Standard < 2.0). The additional assemblies in your output file will redirect the type to .NET Framework's mscorlib.dll.
There is this GitHub issue answering a similar question.
Note that the upcoming .NET Framework 4.7.1 will have the all the required type definitions and forwards out of the box so once a project targets 4.7.1, no additional assemblies will be added to your project's output folder.

C++/CLI Support in .Net Core

Our project structure is like,
native.dll :- This contains pure native code written in c\c++.
This native.dll exposes some functions using *def file.
Wrapper Library(wrapper.dll compiled with .Net framework v4.0) :-
In order to use functionality of native.dll, a Wrapper lib(wrapper.dll)
is written in C++\CLI using :clr\oldsyntax. This wrapper has all
code of Interoperability and Marshalling.
Application(Console App v4.0) directly uses wrapper.dll to use functionality provided
by native.dll.
Now this project needs to run in .Net Core. This means we will have an
.Net Core application that will reference wrapper.dll that in turn will refer
native.dll.
I know this will not directly work. But the issue is whether .Net Core(CoreCLR) supports
C++\CLI (clr\oldsyntax) runtime environment ?
If no, what can be the possible solutions to this application work ?
whether .Net Core(CoreCLR) supports C++\CLI (clr\oldsyntax) runtime environment ?
As far as I know there is no plan to support C++/CLI with .NET Core.
If no, what can be the possible solutions to this application work ?
You can (should) provide a C API. Mono e. g. supports P/Invoke and .NET Core also supports P/Invoke (see also this Stack overflow question and this DllMap related ticket).
Update (2022-09-02): This answer is from 2016. See the other answers (e.g., this) for what is possible with recent .Net Core versions.
Officially announced eventually...
(next wish... support linux # .Net 5 ^^)
https://devblogs.microsoft.com/cppblog/the-future-of-cpp-cli-and-dotnet-core-3/
C++/CLI will have full IDE support for targeting .NET Core 3.1 and higher. This support will include projects, IntelliSense, and mixed-mode debugging (IJW) on Windows. We don’t currently have plans for C++/CLI for targeting macOS or Linux. Additionally, compiling with “/clr:pure” and “/clr:safe” won’t be supported for .NET Core.
The first public previews for C++/CLI are right around the corner. Visual Studio 2019 16.4 Preview 1 includes an updated compiler with “/clr:netcore”
Updat: From replied of origin url:
"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"
(16.4 Preview1 cannot create C++/CLI with .NetCore project.)
191015
16.4 Preview2 Released.
I'v tried asp.net core 3.1 with c++/CLI dll, it works.
(need set plateform to x64 both asp.net core and c++/CLI dll)
.net Core team will only commit (now?) to supporting C++/CLI for Windows only.
The intention was to deliver it for .net Core 3.0. While I haven't found explicit mention of it yet in the release notes, C++/CLI support was a prerequisite for delivering WPF (windows-only), which is now supported in .net Core 3.0.
Support mixed-mode assemblies on Windows - #18013
This issue (#18013) 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.
The github issue (#659) mentioned above by #Tomas-Kubes, Will CoreCLR support C++/CLI crossplat? - #659, is about cross-platform C++/CLI.
BTW, I am getting compiler warnings on "clr\oldsyntax" with VS2017/.net-4.7. So this compiler flag is already deprecated.
UPDATE: This isn't coming till .Net Core 3.1
Another potential solution (though obviously quite a difficult task) if you want to stick with C++ (i.e. expose an OO interface to .NET) might be to have a look at CppSharp from the mono project. It is able to expose native C++ code through an automatically generated C# wrapper. It supports Windows, Linux as well as OSX. However, I don't know if the generated code can be compiled to a .NET standard target (didn't try to). I can only suppose it would because the generated code does not use any fancy API (it is basically interop and marshalling code); and, by the way, it is also possible to customize the generation process (although, once again, probably not an easy task).
For those who are looking at this for general .Net Core stuff without specific clr parameters (as this is a high result on google) Microsoft have written a guide on how to port C++/CLI to .Net Core:
https://learn.microsoft.com/en-us/dotnet/core/porting/cpp-cli
Port a C++/CLI project
To port a C++/CLI project to .NET Core, make the following changes to the .vcxproj file. These migration steps differ from the steps needed for other project types because C++/CLI projects don't use SDK-style project files.
Replace <CLRSupport>true</CLRSupport> properties with <CLRSupport>NetCore</CLRSupport>. This property is often in configuration-specific property groups, so you may need to replace it in multiple places.
Replace <TargetFrameworkVersion> properties with <TargetFramework>netcoreapp3.1</TargetFramework>.
Remove any .NET Framework references (like <Reference Include="System" />). .NET Core SDK assemblies are automatically referenced when using <CLRSupport>NetCore</CLRSupport>.
Update API usage in .cpp files, as necessary, to remove APIs unavailable to .NET Core. Because C++/CLI projects tend to be fairly thin interop layers, there are often not many changes needed. You can use the .NET Portability Analyzer to identify unsupported .NET APIs used by C++/CLI binaries just as with purely managed binaries.
Build without MSBuild
It's also possible to build C++/CLI projects without using MSBuild. Follow these steps to build a C++/CLI project for .NET Core directly with cl.exe and link.exe:
When compiling, pass -clr:netcore to cl.exe.
Reference necessary .NET Core reference assemblies.
When linking, provide the .NET Core app host directory as a LibPath (so that ijwhost.lib can be found).
Copy ijwhost.dll (from the .NET Core app host directory) to the project's output directory.
Make sure a runtimeconfig.json file exists for the first component of the application that will run managed code. If the application has a managed entry point, a runtime.config file will be created and copied automatically. If the application has a native entry point, though, you need to create a runtimeconfig.json file for the first C++/CLI library to use the .NET Core runtime.
There are some more nuances but these are the actual steps to port

Unable to resolve assemblies that use Portable Class Libraries

I'm having a problem with assembly resolution on an end-user machine and I believe it's related to using Portable Class Libraries....
I have a .NET 4.0 application that was originally written in Visual Studio 2010. Recently we upgraded to Visual Studio 2012 and we've created a few projects that are Portable Class Libraries. I don't believe we need these features now, but we're also building a Windows 8 Store application that might benefit from these libraries.
When I compile my project, what exactly does the portable library feature do? I expect that it allows me to run it on different frameworks without modification or recompiling.
When I look at the library in reflector dotPeek it shows the Platform attribute as:
.NETPortable,Version=v4.0,Profile=Profile5
And the references seem 2.0-ish:
mscorlib, Version=2.0.5.0
System, Version=2.0.5.0
System.Runtime.Serialization, Version=2.0.5.0
When I run the application on this end-user's machine, I see an error in the log file:
Could not load file or assembly, 'System.Core, Version=2.0.5.0...'
Googling System.Core 2.0.5.0 seems to refer to SilverLight -- which appears to be one of the targeted frameworks.
This machine does not have Visual Studio installed, but has .NET 4.0 (4.0.3 update)
Is there something I should be doing differently to compile, something I should investigate in my dependencies or something I should be looking to install on the end-user machine? What does the 2.0.5.0 refer to?
For .NET 4, you need an update (KB2468871) for Portable Class Libraries to work. From the KB Article:
Feature 5
Changes to the support portable libraries. These changes include API
updates and binder modifications. This update enables the CLR to bind
successfully to portable libraries so that a single DLL can run on the
.NET Framework 4, on Silverlight, on Xbox, or on the Windows Phone.
This update adds public Silverlight APIs to the .NET Framework 4 in
the same location. The API signatures will remain consistent across
the platform. All modifications are 100 percent compatible and will
not break any existing code.
Also see the "Deploying A .NET Framework App" section of the MSDN Portable Class Library Documentation.
EDIT: Actually, if the machine has .NET 4.0.3 installed as you mention, that should be sufficient. Can you double-check to make sure that it is actually installed?

Confusion over system libariries that ship with mono

I've installed mono 2.10 along with monodevelop and have used monodelveop to code some apps under ubuntu. Several of these apps needed to access to the JavaScriptSerializer, which is part of the System.Web.Script.Serialization namespace.
In order to be able to instantiate and use a JavaScriptSerializer, I had to add a reference to my app in monodevelop - but I see there appear to be two packages that I can chose from: one named "system.web.extensions" and the other named "mono".
If I use the first package (system.web.extensions) I get a runtime error when using the JavaSerializer. I tried using the "mono" reference instead and it works fine.
So far so good. But now, I want to run this same app under windows and I'm getting a "cannot load assembly" error for System.Web.Exceptions.
I'm confused at this point: Why are there two packages shipped with mono/monodevelop for some of these assemblies, and which one(s) should I be using in order to be cross-platform?
Thanks!
Michael
Why are there two packages shipped with mono/monodevelop for some of
these assemblies?
Mono assemblies are kinds of internal assemblies: they provide additional features, not included in the .NET Framework. The System assemblies rely sometimes on these (i.e. Mono.Web for ASP.NET Web services).
Which one(s) should I be using in order to be cross-platform?
Always use the System ones. The Mono assemblies are not available under .NET Framework (unless you ship them manually).
Mono 2.10 provides two versions of the System.Web.Extensions assembly: 1.0.61025.0 and 4.0.0.0. Be sure to use the 4.0 version.
If the problem persists, could you post your code? (for me, no problem using the JavaScriptSerializer)