When you install debug builds on android Xamarin doesn't include Mono runtime in the app instead of this it uses the thing called Shared mono runtime ? I'm curious what the word shared really means? Does is mean that the single instance of the runtime will be lunched and all debug builds(of different apps) will run in this single instance of Mono runtime, or this means that Mono will be delivered to the device only once and all debug builds will run its own instance of that shared runtime(So it will just not be delivered with every app install)
P.S. Although this post looks similar its accepted answer just copy-pastes some ambiguous info from Xamarin docs which is not very informative and doesn't really answers the question
Related
As far as I understand, applications built with Xamarin deploy in every application a mono runtime that works beside the ART, communicating between each other.
Knowing the current android limitations that starting API-28 you cannot start binaries, I was wondering how actually the runtime gets started?
This is briefly described in the Xamarin docs here: https://learn.microsoft.com/en-us/xamarin/android/internals/architecture#application-startup
If you take a look at the build output of your app in obj/Debug/android/src/mono you will notice a couple of java files.
MonoRuntimeProvider.java
This creates a ContentProvider, which is responsible for launching the mono runtime and starting your App.
MonoPackageManager_Resources.java
This class is called by the MonoRuntimeProvider, which is a helper class to find the Assembly containing your App.
The MonoRuntimeProvider is registered in the AndroidManifest.xml in the Application tag. Which means that when your App starts, the Content provider will also start, and in turn starts the Mono Runtime.
At build time Android Callable Wrappers (ACW) are generated for your Activities (and many other types as well). This is a way to invoke managed (C# code) from the Android world.
If you try to decompile your App, you will see that in the constructor of such ACW's there is a call to the mono runtime register and activate the managed type.
As for the limitations in API-28, I don't see anywhere in the docs where they mention anything about not being able to start binaries.
There are some Restrictions on non-SDK interfaces. If it was the case that you were not able to consume binaries in your Android App it would mean that all Apps consuming C/C++ NDK libraries would be broken.
There has been some limitations to where you can access such libraries. In the past you would be able to use some binaries outside of your Applications scope, which were bundled with Android, this is not allowed anymore and you need to bundle this with your App yourself.
I've read through a lot of documentation on Xamarin and my understanding is that it exposes the native APIs on each platform via C# and .NET, and this way, offers a sort of one-to-one binding. The native build produced contains some of the applicable .NET libraries (based on linker optimisation).
However, I can't seem to find any information about what actually happens within the native build itself.
Assuming my understanding is correct, my question is:
Within the native build, does the code you've written call the native API functions via a call to native .NET functions included in the build?
The short answer is: yes, it calls native API's through .NET code that runs on Mono, via the binding concept you already seem to be familiar with.
Xamarin uses these bindings to call the native code from your C# code. There are a few differences depending on the platform you are running on.
iOS
Your IPA-file will contain 2 things:
The executable of your .NET code (AOT-compiled), which is run through the Mono runtime
Native libraries, which use the objective-C runtime. The .NET code calls these libraries/API's via bindings.
Both the Mono runtime and the Objective-C runtime are running on top of a UNIX-like kernel.
Take a look at this Xamarin iOS architecture documentation for a more extensive explanation.
Android
Android is a little more complex to understand and explain. This is because some of the API's are only exposed through the Android Runtime API.
The bindings in Android are working through concepts such as:
"Android Callable Wrappers" (Android Runtime to Mono)
"Managed Callable Wrappers" (Bindings to Android Runtime API's)
The Xamarin Android architecture documentation explains these concepts and inner workings in great detail.
I'm trying to rewrite IL code dynamically at runtime. While this is quite well documented for .NET framework applications by using the Profiling API I can't find anything similar for UWP applications.
Because I have a suite of automated function tests, I need to setup the profiling environment and start a sample app programmatically.
Attempt 1
This question explains how to enable a debugger (as far as I understand a profiler is essentially a debugger) and programmatically start a UWP app.
So from my bootstrapper I call IPackageDebugSettings::EnableDebugging followed by IApplicationActivationManager::ActivateApplication.
Anyway I can't figure out how to implement the debugger. The debugger (which is an executable) is called with the following arguments:
-p 3836 -tid 6180
Both numbers change on every run. While p seems to be the process id of the debugged process, I have no idea what tid could be or how I have to use the arguments to control the debugged app (register for module load events, trigger rejits etc.).
Attempt 2
I found this issue on the Core CLR repo which is about enabling the Profiling API for Core CLR apps. The issue contains a link to a sample profiler repo.
So profiling for Core CLR apps seems to basically work the same way as it does in .NET framework apps (with some restrictions). From my bootstrapper I tried to set the appropriate environment variables (i.e. CORECLR_ENABLE_PROFILING, CORECLR_PROFILER and CORECLR_PROFILER_PATH) followed by IApplicationActivationManager::ActivateApplication.
However the profiler doesn't attach.
I'm quite sure that in general it is possible to profile UWP applications because JetBrains' dotTrace can do it.
Any ideas?
Backgrond
I am very experienced in C and pretty new to Android and Java, but this is rather environmental issues that programming.
I have developed an administrative application in ANSI-C to be ported to any OS, just adding a UI in OS-dependent code. Well it uses quite some memory, especially for huge user files. I have a working Win32 program, trying to make an Android app using Android Studio with NDK.
Android studio bundle NDK installation works fine
I have installed and made a Win7 ultimate Android Studio 1.3 with bundle NDK and made compiling and running the ActionbarStyled (non NDK) hello-jni (NDK) sample in the emulators, smooth and nice. I also in the emulator been successfully running Hello-jni sample with a bunch of extra c-files (not called, at present just garbage, compiled without errors, in this step)
Then I tried to connect my Samsung TAB3 SM-T110 template (one need a Win7 Samsung driver SAMSUNG_USB_Driver_for_Mobile_Phones.zip) to my Win7 and tried it. ActionbarStyled sample works just fine. So does the Hello-JNI sample.
But
Running Hello-jni sample with a bunch of extra c-files I get this error message:
Error while starting native debug session: java.lang.IllegalArgumentException: Unable to find process for com.example.hellojni on device samsung-sm_t110-47900bc50c0c3100
I try to understand what is the issue? Is it lack of memory, the Samsung is full of active running apps, the emulator obviously not.
What makes the Samsung unit to halt the application? Error message is not that describing?
Some more questions supporting handling this kind of issues
We are talking about Android studio 1.3 bundle NDK, how much from earlier setups (in articles) are applicable for this new future NDK standard use?
Memory?
Running the pure Hello-jni sample I have about 6Mb memory (where 5Mb are used), that is pretty poor for my needs, is there something I need to do have my app getting more memory allocated? Is the error message due to running out of memory?
How large Android Apps are possible to do? Are we in a world like the 8-bit DOS 64Kb segment business again? I know it from past but that isen't the case? And if need to know to handle it. The Library for unrestricted heap memory for bitmaps using NDK on Android question is interesting to read, but here we are talking about the jni (C-)code rather than java.
Compiler optimisation?
I have some really huge C-files due to that they are machine generated converting an XML library of documents to C-code (made a program writing C-code from the XSD definitions). In an application I most of the time use only say 5% of all the C-function, the rest are in Windows dev studio/compiler optimised away. Certainly I can reorganise my source code to quite some extra work, but I need to know. How is the optimisation in the Android Studio NDK support?
Thing is in this test no extra C-functions are called except the same regular as in the hello-jni sample. Actually the compiler should make exactly the same in both cases (the modified and the original hello-jni). But obviously it don't. Please explain a bit more how the environment works so I know?
General interest
I tried to find any spot in the Android developers that describe things like compiler behaviour, memory management and environment (the Java handles such completely different, but in C-programming on need to be aware). I think for NDK use it would be interesting getting a good answer here, for the general understanding of the environment, somewhere in the Android developer pages, rather than here. That also includes how the compiler optimises in different situations. But also how to make environmental settings.
I am talking about a small game engine using C# for game programming.
So, I have a C++ app embedding mono runtime (I call it 'launcher'). And I have an assembly written in C# which is my game engine class library. The launcher launches the assembly as it is suggested in Embedding Mono.
And now the interesting part!
The launcher implements in C++ miscelaneous functions which are exposed to the mono runtime as internal methods of my game engine classes. That is why my game engine assembly is nothing without the launcher which implements a huge part of the engine in C++.
The question: How am I supposed to debug my C# assembly? And what is more important, how am I supposed to debug a Game which I am going to write in C# ???
As you understand I cannot debug the assembly using MonoDevelop Debugger because it won't receive internal C++ implementations of some of its methods.
What I need is to run the Launcher. The launcher then will launch C# assembly using embedded mono runtime. And then I need something to connect to the launched assembly to allow its debugging.
Or any other way. Thank you!
I recommend using the Mono Soft Debugger. It's been included in the Mono runtime since Mono 2.6, and is more reliable than the old hard debugger, and also much more portable.
The Mono soft debugger can be started by passing options using the --debugger-agent commandline argument to the Mono runtime. This can be done from an embedding host by constructing a fake set of commandline arguments and passing it to mono_jit_parse_options. For example, the Moonlight browser plugin uses the debugger agent values from MOON_SOFT_DEBUG environment variable if it is set.
Typically debugger options are something like
--debugger-agent="transport=dt_socket,address=$ADDRESS:$PORT"
which will cause the app to try to connect to debugger listening on the given address, and pause until it establishes a connection. Note that the connection is established over TCP/IP, which means remote debugging is very easy to set up, and even on the local machine you would use localhost. Additional options are documented on Mono's man page.
The other piece you need is the debugger GUI/controller, to listen for the connection from your app, and handle stepping/visualizing, etc. I would suggest using MonoDevelop. There's a library for the debugger wire protocol called Mono.Debugger.Soft.dll, but it's fairly low-level, and although Mono Tools for Visual Studio supports connecting to the soft debugger, it's not yet extensible in a way that would allow debugging Mono embedding hosts.
Using MonoDevelop to accept debugger connections from embedding hosts currently requires creating an addin, but this is fairly straightforward. Take a look at the Moonlight debugger addin for an example. For simple use cases I would suggest that you don't define a whole new project type but just create a debug handler that handles existing DotNetExecutionCommand projects, so you can run->run with...->your custom debugger.
The monodevelop-list mailing list is a good resource if you have more questions.
Make use of network debugging.
You could use the Soft Debugger to debug the Mono parts, and then use remote debugging for the C++ parts.