FAQ: Technical
Mono Runtime
Where can I find the Technical Documentation to the Mono Runtime?
The documentation that used to be available on the mono/docs directory is now being moved into this web site and is available in the Runtime Documentation section.
Mono Platforms
What operating systems does Mono run on?
Mono runs on Linux, UNIX and Windows systems. For a more detailed list, see the Supported Platforms page.
Is Mono Binary Compatible with Windows?
Yes, Mono is binary compatible with Windows. Which means that you can run binaries produced by .NET compilers from Microsoft and other vendors.
When porting your applications, you should make sure that you test its functionality as differences in the underlying operating system and differences in the VM implementations (bugs, missing features) might affect your application.
Mono does not have every .NET API implemented and when executing a binary from Windows that consumes an unimplemented API you might get an obscure message about tokens not being found.
In these cases it is useful to compile your application with Mono’s C# compiler just to ensure that you are consuming APIs that are supported.
This is not a perfect solution, as some APIs in Mono throw NotImplementedExceptions in certain cases, so you still should test your application with Mono. If you care about application portability, check MoMA, the migration analyzer.
Are there any reasons to build on Mono instead of using Visual Studio and copying the binaries?
In general, you can continue to use Visual Studio to write your code if you feel comfortable doing so.
Using Linux to develop will encourage you to test your software on Linux more frequently and if you have the chance, it will also help you to “dogfood” your own product.
Jonathan Pryor adds:
The benefit is that you can more easily know which APIs exist vs. which do not. In general, if an API doesn’t exist within Mono, we try NOT to provide the method within the assembly (with a default version throwing NotImplemetedException()), so that you can use gmcs compile to determine if all the APIs you use actually exist.
This isn’t always possible, so there are several instances where a NotImplementedException is thrown, but when a NIE can be avoided by omitting the member, the member is omitted.
The alternative is to build under .NET and run under Mono, which leaves you (more) at the mercy of NotImplementedException’s or MissingMememberException. A decent regression test platform should find these issues, so this might not be an actual problem.
Can I run Mono applications without using ‘mono program.exe’?
Yes, this is possible on Linux systems, to do this, use something like:
if [ ! -e /proc/sys/fs/binfmt_misc/register ]; then
/sbin/modprobe binfmt_misc
mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
fi
if [ -e /proc/sys/fs/binfmt_misc/register ]; then
echo ':CLR:M::MZ::/usr/bin/mono:' > /proc/sys/fs/binfmt_misc/register
else
echo "No binfmt_misc support" exit 1
fi
This practice is discouraged as it is not portable.
It is better to follow the pattern described in the Application Deployment Guidelines and use a wrapper script to invoke Mono. That has several advantages (portability, ability to write relocatable applications, avoiding pollution of bin directories and allowing for flags and options to be passed to Mono).
If you create software with MonoDevelop and you have selected “Unix Integration”, the scripts will be generated by default.
What architectures does Mono support?
See our Supported Platforms page.
Can Mono run on Windows 9x, or ME editions?
Mono has not been compiled on Windows 9x or ME for many years and it is not actively developed or maintained on that configuration.
That being said, the following information is from the days of Mono 1.2.x and might be useful to someone trying to port it:
Mono requires Unicode versions of Win32 APIs to run, and only a handful of the “W” functions is supported under Win9x. There is Microsoft Layer for Unicode that provides implementation of these APIs on 9x systems.
Unfortunately it uses linker trick for delayed load that is not supported by ld, so some sort of adapter is necessary. You will need MSLU and one of the following libs to link Mono to unicows.dll http://mono.eurosoft.od.ua/files/unimono.zip or alternatively search the net for “libunicows”.
Why support Windows, when you can run the real thing?
There are various reasons:
-
Supporting Windows helps us identify the portable portions of Mono from the non-portable versions of it, helping Mono become more portable in the future.
-
It assists us since we can isolate problems in Mono by partitioning the problem (is it a runtime issue, or an OS issue?).
-
About half the contributors to Mono are Windows developers. They have many different reasons for contributing to the effort, and we find it very important to let those developers run the runtime on Windows without forcing them to use a new operating system.
-
Mono does not heavily modify the windows registry, update system DLLs, install DLLs to the Windows/System32 path.
-
It helps Windows-based developers to test their code under Mono before they deploy into Linux.
-
Mono and applications that embed Mono can be deployed without an installer (you can “xcopy” deploy your application and the required Mono files without installing the .NET runtime).
-
Some applications and libraries premise pair (or more) of applications, such as clients and servers. Windows version helps mixed solutions of .NET and Mono easier, for example by running one on .NET and one on Mono locally on Windows.
A reader comments:
In other words, I knew Mono would not cause
any legacy enterprise applications
to stop working - and it hasn't. However,
our CIO is against it because of the
changes that would be made to Windows 2000,
such as, affecting security.
Another user comments:
By the way, the Mono libraries,
including corlib, needed to support the
application total 14MB so fit easily
on even the smallest memory sticks.
How to detect the execution platform ?
Newer code should use the System.Runtime.InteropServices.RuntimeInformation
APIs.
Historically, the execution platform could be detected by using the System.Environment.OSVersion.Platform
value. However correctly detecting Unix platforms, in every cases, requires a little more work. The first versions of the framework (1.0 and 1.1) didn’t include any PlatformID
value for Unix, so Mono used the value 128. The newer framework 2.0 added Unix to the PlatformID
enum but, sadly, with a different value: 4 and newer versions of .NET distinguished between Unix and macOS, introducing yet another value 6 for macOS.
This means that in order to detect properly code running on Unix platforms you must check the three values (4, 6 and 128). This ensure that the detection code will work as expected when executed on Mono CLR 1.x runtime and with both Mono and Microsoft CLR 2.x runtimes.
using System;
class Program {
static void Main ()
{
int p = (int) Environment.OSVersion.Platform;
if ((p == 4) || (p == 6) || (p == 128)) {
Console.WriteLine ("Running on Unix");
} else {
Console.WriteLine ("NOT running on Unix");
}
}
}
Notice that as of Mono 2.2 the version returned on macOS is still 4 for legacy reasons, too much code was written between the time that the macOS value was introduced and the time that we wrote this text which has lead to a lot of user code in the wild to not cope with the newly introduced value.
A better way of testing for Unixness is to make tests that are feature specific instead of dividing the code in Unix vs Windows. For example, for file system operations, it is better to use the path character separator and compare it for ‘/’ or ‘\’ as that would not depend on the actual enumeration value.
How can I detect if am running in Mono?
Having code that depends on the underlying runtime is considered to be bad coding style, but sometimes such code is necessary to work around runtime bugs. The supported way of detecting Mono is:
using System;
class Program {
static void Main ()
{
Type t = Type.GetType ("Mono.Runtime");
if (t != null)
Console.WriteLine ("You are running with the Mono VM");
else
Console.WriteLine ("You are running something else");
}
}
Any other hack, such as checking the underlying type of System.Int32 or of other corlib types, is doomed to fail in the future.
How can I detect if my code is compiled by the Mono mcs compiler?
Having code that depends on the underlying compiler is considered to be bad coding style, but sometimes such code is necessary. You can do it by checking the special __MonoCS__
symbol:
using System;
class Program {
static void Main ()
{
#if __MonoCS__
Console.WriteLine ("Compiled with the Mono compiler");
#else
Console.WriteLine ("Compiled with something else");
#endif
}
}
Does Mono run on very small systems
The current default minimal mono install requires less than 4 MB of disk space and 4 MB of memory (plus disk and memory required by the operating system and programs running on mono). Mono plus basic Gtk# support requires less than 8 MB of disk space. To reduce further the footprint of Mono, see the Small footprint page.
Compatibility
Can Mono run applications developed with the Microsoft.NET framework?
Yes, Mono can run applications developed with the Microsoft .NET Framework on UNIX. There are a few caveats to keep in mind: a few API calls might be missing and in some cases the Mono behavior might be incorrect.
Will missing API entry points be implemented?
Yes, the goal of Mono is to implement precisely the .NET Framework API (as well as compile-time selectable subsets, for those interested in a lighter version of Mono).
If the behavior of an API call is different, will you fix it?
Yes, we will. But we will need your assistance for this. If you find a bug in the Mono implementation, please file a bug report. Do not assume we know about the problem, we might not, and using the bug tracking system helps us organize the development process.
Can I develop my applications on Windows, and deploy on a supported Mono platform (like Linux)?
Yes, you can. As of today, Mono is not 100% finished, so it is sometimes useful to compile the code with Mono, to find out if your application depends on unimplemented functionality.
Will applications run out the box with Mono?
Sometimes they will. But sometimes a .NET application might invoke Win32 API calls, or assume certain patterns that are not correct for cross-platform applications.
You can find which native methods an assembly is using by using MoMA.
or alternatively, by using monodis like this:
monodis --implmap file.exe
The above command will list all of the invocations that the application has.
Gendarme also gives you some interoperability warnings.
Must I have mono to create or run Gtk# applications in Windows?
No. Currently you can use the Gtk-Sharp Installer for .NET Framework which when coupled with the Microsoft .NET Framework, will allow you to build .NET applications that use Gtk# as their graphical user interface.
What is a 100% .NET application?
A ‘100% .NET application’ is one that only uses the APIs defined under the System namespace and does not use P/Invoke. These applications would in theory run unmodified on Windows, Linux, Solaris, macOS and others. Note that this requirement also holds for all assemblies used by the application. If one of them is Windows-specific, then the entire program is not a 100% .NET application. Furthermore, a 100% .NET application must not contain non-standard data streams in the assembly. For example, Visual Studio .NET will insert a #-
stream into assemblies built under the “Debug” target. This stream contains debugging information for use by Visual Studio .NET; however, this stream can not be interpreted by Mono (unless you’re willing to donate support). Thus, it is recommended that all Visual Studio .NET-compiled code be compiled under the Release target before it is executed under Mono.
Can I execute my Visual Studio .NET program (Visual Basic .NET, Visual C#, Managed Extensions for C++, C++/CLI, etc.) under Mono?
Yes, with some reservations.
The .NET program must either be a 100% .NET application, or (somehow) have all dependent assemblies available on all desired platforms. (How to do so is outside the bounds of this FAQ). Or if the application uses P/Invoke, the invoked native libraries must exist on other platforms as well.
Mono must also have an implementation for the .NET assemblies used. For example the System.EnterpriseServices namespace is part of .NET, but it has not been implemented in Mono. Thus, any applications using this namespace will not run under Mono.
With regards to languages, C# applications tend to be most portable. Visual Basic .NET applications are portable, but Mono’s Microsoft.VisualBasic.dll implementation is incomplete. It is recommended to either avoid using this assembly in your own code, only use the portions that Mono has implemented, or to help implement the missing features. Additionally, you can set ‘Option Strict On’, which eliminates the implicit calls to the unimplemented Microsoft.VisualBasic.CompilerServices.ObjectType class. (Thanks to Jörg Rosenkranz.)
Managed Extensions for C++ and C++/CLI are least likely to operate under Mono. Mono has support for mixed-mode assemblies (that is, assemblies containing both managed and unmanaged code, which Managed C++ can produce) on Windows. You need a fully-managed assembly to run under other platforms, and getting the Visual C++ .NET compiler to generate such an executable can be difficult. You need to use only the .NET-framework assemblies, not the C libraries (you can’t use printf(3) for example.), and you need to use the linker options /nodefaultlib /entry:main mscoree.lib
in addition to the /clr
compiler flag. You can still use certain compiler intrinsic functions (such as memcpy(3)) and the STL.
You should also see Converting Managed Extensions for C++ Projects from Mixed Mode to Pure Intermediate Language at MSDN. Finally, you can use PEVERIFY.EXE from the .NET SDK to determine if the assembly is fully managed.
Thanks to Sergey Chaban for the linker flags to use.
C++/CLI meanwhile needs to use the /clr:pure
or /clr:safe
compiler flag to avoid the use of mixed-mode assemblies.
For more details see our C++ page.
Does Mono have a Global Assembly Cache (GAC)?
Yes, Mono has a Global Assembly Cache.
It operates in a similar way to the .NET Global Assembly Cache, but has a few extensions, see the Assemblies and the GAC article for details.
What about serialization compatibility? Can I serialize an object in Mono and deserialize it in MS.NET or vice versa?
The serialization format implemented in Mono is fully compatible with that of MS.NET. However, having a compatible format is not enough. In order to successfully exchange serialized objects, the corresponding classes need to have the same internal structure (that is, the same public and private fields) in both sides.
If you are serializing your own classes, there is no problem, since you have control over the assemblies and classes being used for serialization.
However, if you are serializing objects from the framework, serialization compatibility is not guaranteed, since the internal structure of those objects may be different. This compatibility is not even guaranteed between different MS.NET versions or Mono versions.
Our policy is to do our best to make the framework classes compatible between Mono and MS.NET, however sometimes this is not possible because the internal implementation is too different. Notice also that when we change a class to make it compatible with MS.NET, we lose compatibility with older versions of Mono.
In summary, if you are designing an application that will run in different environments and platforms which are not under your control, and which need to share serialized objects (either using remoting, plain files, or whatever), you must be careful with what objects you share, and avoid objects from the framework when possible.
(Notice that this only applies to serializers based on the System.Runtime.Serialization framework, and does not apply to the XmlSerializer).
Can I use Mono to build applications for the Compact Framework?
Binaries produced by Mono do not contain the same public key expected by the compact framework. The compact framework will refuse to load applications that have been compiled with this key.
JB Evain produced a patcher that can be used to modify binaries produced by Mono to run on the Compact Framework, you can find it here.
Patches binaries will be loaded in the Compact Framework, but if your assembly consumes features that are not present on it, your software will crash.
How can I map a Windows P/Invoke Library into a Unix library?
See the <dllmap> and <dllentry> directives.
Development Tools
Does Mono have a debugger?
Yes, see our Debugger page for more information.
Also look at the Guide:Debugger for a tutorial and reference guide to the Mono debugger.
Debugger Tutorial
See the Guide:Debugger for a debugger tutorial and reference guide.
What Platforms does the Debugger Support?
Currently the Mono Debugger only supports Linux on x86 and x86-64 platforms.
How can I debug my programs?
You must have the Mono Soft Debugger installed (sdb), and compile your code with debugging information, this is done by passing the -debug flag to the compiler:
$ csc -debug sample.cs
$ sdb sample.exe
(sdb) run
Can I convert Microsoft PDB files to Mono MDB files?
You can convert PDB files to MDB files using “pdb2mdb” in mono tree, a program written by JB Evain. For details see his blog post. For earlier effort by Robert Jordan, see his emails on the subject here and here.
Does Mono have a profiler?
Mono has a built-in profiler which can be activated by running Mono with the –profile argument. The profiler can be further tuned, see the manual page for mono (mono(1)) for more details. Most of the time you want to use the statistical profiler (which has a very low performance overhead):
/path/to/mono --profile=default:stat program.exe
If you have binutils installed (the addr2line program specifically), you’ll get detailed profiling info also on unmanaged code.
In addition it is possible to create custom profilers using Mono’s profiling interface. For a list of existing profilers for Mono see our Performance Tips page.
A more advanced profiler is the Logging Profiler
Does Mono have a memory profiler?
Mono has several memory profilers: a built-in one (see manual page), HeapShot for information about the Mono live memory usage, HeapBuddy for memory allocation patterns and OprofileWithAnonJitData using OProfile to profile JITed code.
See the Profile page for more information.
Does Mono have Code Coverage Tools?
Mono has a bundled code coverage tool that you can use with your applications. Use the “coverage” profiler, like this:
mono --profile=cov demo.exe
See the Code Coverage page for more information.
Does Mono have some kind of tracing facility?
The Mono runtime has a built-in tracing facility to trace the method execution and it reports parameters passed, values returned and exceptions thrown. This is enabled with the –trace flag to the Mono runtime.
The tracing facility has a simple syntax for limiting the scope of traces, see the mono manual page for more details on this facility.
How can I debug problems with my DllImports?
You can export the following environment variables to turn on DllImport logging, it is useful when tracking down the source of a problem when loading a library:
MONO_LOG_LEVEL=”debug” MONO_LOG_MASK=”dll” mono program.exe
Web Services
How is Mono related to Web Services?
Mono is only related to Web Services in that it will implement the same set of classes that have been authored in the .NET Framework to simplify and streamline the process of building Web Services.
But most importantly, Mono is an Open Source implementation of the .NET Framework.
Can I author Web Services with Mono?
You will be able to write Web Services on .NET that run on Mono and vice-versa.
What does Mono support for Web Services?
As of today, Mono support Web services in a couple of forms:
- Remoting SOAP channels (as well as binary channels)
- ASMX Web Services (System.Web.Services)
- WCF, preliminary
You can use Mono for remoting and ASMX web services either as client or as server (or both). ASMX Web Service client also works on MonoTouch.
WCF client is supported in Mono, Moonlight and MonoTouch. WCF server implementation effort is ongoing. Note that the supported WCF bindings are limited to some basic ones.
Can I use CORBA?
Yes. The CLI contains enough information about a class that exposing it to other RPC systems (like CORBA) is really simple, and does not even require support from an object.
Remoting.CORBA is a CORBA implementation that is gaining momentum. Building an implementation of the Bonobo interfaces once this is ready should be relatively simple.
There are other CORBA implementations for .NET available as well.
Can I serialize my objects to other things other than XML?
Yes. We support runtime/binary serialization as well as XML serialization. You also write your own serialization providers. We also support WCF serialization (binary, XML, JSON).
MonoDoc
What is MonoDoc?
MonoDoc is a graphical documentation browser for the Mono documentation: class libraries, tutorials and manual pages. Currently, monodoc has a GUI front-end written in Gtk# and a Web front-end using ASP.NET
The contents of Monodoc today are visible on the web here
More information about the Mono documentation can be found on the Documentation page.
Development Tools and Issues
Will it be possible to use the CLI features without using byte codes or the JIT?
Yes. The CLI engine will be made available as a shared library. The garbage collection engine, the threading abstraction, the object system, the dynamic type code system and the JIT are available for C developers to integrate with their applications if they wish to do so.
What kind of rules make the Common Intermediate Language useful for JITers?
The main rule is that the stack in the CLI is not a general purpose stack. You are not allowed to use it for other purposes than computing values and passing arguments to functions or return values. At any given call or return instruction, the types on the stack have to be the same independently of the flow of execution of your code.
Is it true that the CIL is ideal for JITing and not efficient for interpreters?
The CIL is better suited to be JITed than JVM byte codes, but you can interpret them as trivially as you can interpret JVM byte codes.
Is there any way I can install a known working copy of mono in /usr, and an experimental copy somewhere else, and have both copies use their own libraries?
Yes. Just use two installation prefixes. Use --prefix=/whatever/you/prefer
option when configuring mono.
How should I write tests or a tests suite?
It is up to you, but we use NUnit for testing our own class libraries as a choice.
Is it possible to build a C# file to some sort of intermediate format which can linked into a final module, like the traditional .c -> .o -> .so path?
You can use:
csc /target:library file1.cs
csc /target:library file2.cs
csc /target:exe file1.dll file2.dll /out:mybin.exe
It is not worth doing the above for individual files. The C# compiler is so fast that usually the cost of compiling a few hundred source files is smaller than the cost of creating the separate dll files.
Also the final results will be an assembly that references all of the other .dll files, it wont be a single unit.
If you want to merge the assemblies, you could try the prototype “merge” tool that is part of Cecil.
Is remoting supported and working in Mono?
The remoting infrastructure is in place. We have implementations of the TcpChannel, HttpChannel and the Soap and Binary Formatters. They are compatible with .NET.
However, some classes from the library may have a different binary representation, because they may have a different internal data structure, so for example you won’t be able to exchange a Hashtable object between Mono and MS.NET. It should not be a problem if you are using primitive types, arrays or your own classes. If you have problems, please post a test case.
My C code uses the __stdcall which is not available on Linux, how can I make the code portable Windows/UNIX across platforms?
Replace the __stdcall attribute with the STDCALL macro, and include this in your C code for newer gcc versions:
#ifndef STDCALL
#define STDCALL __attribute__((stdcall))
#endif
How does Unicode interact with Mono?
These are a few bits that you might want to know when dealing with Unicode strings in Mono and Unix:
- Mono compilers will default to the current language encoding as their native encoding. If your LANG environment variable contains the terminator UTF-8 (for example mine is LANG=en_US.UTF-8) it will process its input files as UTF-8
- You can control the encoding used by the compilers using the -codepage: command line option, for the special case of utf-8, you can use: -codepage:utf8 to inform the compiler that your sources are in UTF-8, for more codepages, see the manual page for the compiler.
- CIL executables generated by the Mono compilers store everything in UTF-16 encodings.
-
If you are dealing with ASP.NET that invokes the compiler automatically for you, you can control the encoding used by specifying this on the web config file. See the reference for [[Config_system.web_globalization web/globalization] for details.
The above takes care of converting the input you provide to Mono compilers and runtimes into Unicode. Another issue is how these characters get rendered into the screen.
For console output Mono will use the encoding specified in your LANG environment variable to display the Unicode strings that the program has. If your LANG variable does not allow for the full range of Unicode strings to be displayed (for example, LANG=en alone) then only the subset supported by that specific character set can be displayed.
I just made a change in my code and am getting Segfaults, what is it?
Segfaults are typically the result of a stack overflow, these are caused by recursive invocations of a method, and these happen frequently with OO code, as developers forget to call the “base” method, for example:
class Child : Parent {
public override GetNumber ()
{
return GetNumber () + 1;
}
}
When the developer really wanted:
class Child : Parent {
public override GetNumber ()
{
return base.GetNumber () + 1;
}
}
Although Mono has support for turning these into a StackOverflowException, the code that does this introduces an instability into the Garbage Collector, so it is no longer being turned on by default.
What are the issues with FileSystemWatcher?
The Mono implementation of FileSystemWatcher has a number of backends, the most optimal one, the one with fewer dependencies is the inotify-backend (available in Mono 1.1.17 and newer versions).
With this backend the kernel provides Mono with updates on any changes to files on the file system but it requires an inotify-enabled kernel, which only newer Linux distributions ship.
In older Linux systems, you must have installed FAM or Gamin (it will work with either one). You might need the -devel packets installed.
For the *BSD family, there’s a Kqueue based implementation that will be used when detected at runtime.
If none of the above work, Mono falls back to polling the directories for changes, which far from optimal.
Am using Mono with FakeRoot an my application hangs, what can I do?
Try this:
mkdir /tmp/fakeroot-wapi
MONO_SHARED_DIR=/tmp/fakeroot-wapi fakeroot ...
Otherwise mono would try to write to /root/.wapi/ because fakeroot doesn’t fake the pwent functions that Mono is using to obtain the home directory.
Mono and ASP.NET
See FAQ: ASP.NET
Mono and ADO.NET
What is the status of ADO.NET support?. Could I start migrating applications from MS.NET to Mono?
The ADO.NET support is fairly complete and there are many database providers available.
In developing the data architecture for the application are there and objects I should stay away from in order to insure the smoothest possible transition (minimum code rewrite) to Mono’s ADO.NET implementation? (For example, strongly typed datasets versus untyped datasets, etc…)
We are implementing all the classes in Microsoft .NET’s System.Data, so you can be sure that things will work the same in Mono as with the Microsoft implementation. There is strongly typed dataset support in Mono now.
Can you connect to a Sybase database using Mono?
Yes. use Mono.Data.SybaseClient. First of all you have to create a SybaseConnection, and then, from it, use it as any other IDbConnection-based class. See here for more info.
Has the MySQL Connector/Net replaced ByteFX.Data
Yes it has. MySQL Connector/Net is made by MySQL AB and are the best people who would know how to access their databases. The author of ByteFX.Data no longer develops ByteFX.Data because he is employed by MySQL AB now. See here for more info.
How do I connect to a SQLite database?
Use Mono.Data.SqliteClient. Make sure you are using at least Mono 1.1.4 since SQL Lite provider does not work in the Mono 1.0.x releases and prior. Use a connection string like “URI=file:SqliteTest.db” if you are using SQL Lite version 2.x or use “version=3,URI=file:SqliteTest.db” if using SQL Lite version 3.x. See SQLite for more info.
What provider do I use to connect to PostgreSQL?
You would use Npgsql which is included with Mono. It is also included with the Win32 installer for PostgreSQL 8.0 which runs natively on Windows. See here for more info.
Mono and EnterpriseServices
The following document link to the status of EnterpriseServices in Mono:
Mono and Java
Why don’t you use Java?
After all, there are many languages that target the Java VM.
You can get very good tools for doing Java development on free systems right now. Red Hat has contributed a GCC front-end for Java that can take Java sources or Java byte codes and generate native executables; Transvirtual implemented Kaffe a JIT engine for Java; Intel also has a Java VM called ORP.
The JVM is not designed to be a general purpose virtual machine. The Common Intermediate Language (CIL), on the other hand, is designed to be a target for a wide variety of programming languages, and has a set of rules designed to be optimal for JITers.
Could Java target the CLI?
Yes, Java could target the CLI, Microsoft’s J# compiler did that. The IKVM project builds a Java runtime that works on top of .NET and on top of Mono. IKVM is essentially a JIT compiler that translates from JVM bytecodes into CIL instructions, and then lets the native JIT engine take over.
Is it possible to write a JVM byte code to CIL converter?
Yes, this is what IKVM does.
Could mono become a hybrid CIL/java platform?
This can be obtained easily with IKVM.
Can Mono or .NET share system classes (loaded from mscore.dll and other libs) or will it behave like Sun’s Java VM?
What you can do with mono is to load different applications in their own application domain: this is a feature of the CLR that allows sandboxing applications inside a single process space. This is usually exploited to compartmentalize different parts of the same app, but it can also be effectively used to reduce the startup and memory overhead. Using different appdomains the runtime representation of types and methods is shared across applications.
Extending Mono
Would you allow other classes other than those in the specification?
Yes. The Microsoft class collection is very big, but it is by no means complete.
Do you plan to Embrace and Extend .NET?
Embracing a good technology is good. Extending technologies in incompatible ways is bad for the users, so we do not plan on making incompatible changes to the technologies.
If you have innovative ideas, and want to create new classes, we encourage you to make those classes operate correctly well in both Mono and .NET. Today Mono ships with a number of extra libraries that were developed either by members of the Mono community, or other groups. In some cases, we have found the bits from Microsoft to be incomplete, but we avoid breaking the API, instead we expose the missing functionality in new assemblies (see Mono.Security).
Do you plan on exploring, changing other parts?
The Mono team at Xamarin is currently focused on improving Mono’s performance, platform support, coverage, quality and features, so we are likely going to be busy doing those things.
But Mono has already been used as a foundation for trying out new ideas for the C# language (there are three or four compilers derived from Mono’s C# compiler) and a number of innovative ideas (like continuations for the VM) have been implemented as research prototypes on top of Mono.
We need to explore in a case-by-case basis which of these ideas can be integrated into Mono, we are certainly open to the idea of getting some of these ideas merged into Mono, but in addition to the standard considerations for any contributed code we have to take into account things like whether we can maintain it effectively, whether it makes too many changes to Mono, whether it is a clean and maintainable implementation.
So in short: we are open to the idea of deviating from .NET for research purposes and when the idea is good, but we will incorporate based on a case-by-case study of the proposal.
Is there any way I can develop the class libraries using Linux yet?
Yes. Mono has been self hosting since March 2002.
I have a great library that I want to contribute, will you take it?
The first step for a library to be integrated into Mono is for the library to be licensed under the terms of the MIT X11 license.
These days we recommend that third-party libraries are maintained independently of the core of the Mono class libraries and that they are shipped independently with their own release schedule.
The problem with bundling libraries with Mono is that they have a higher requirement for backwards-compatibility, so any breakage in the API requires us to ship a new version of the library and keep the old version around. Maintaining too many libraries can be cumbersome after a while.
We recommend that the libraries are given a chance to evolve, and have their API mature before they are installed in the GAC, which is the first step towards being considered for inclusion with Mono.
There is another downside that library developers face when bundling libraries with Mono: their release schedule ends tied to Mono, which might be too slow for a rapidly evolving library. This also imposes extra work if you try to match our release and development schedules.
A better practice is to keep the library on its own schedule, release it on its own schedule and ensure that packages are available for most distributions.
Portability
Will Mono only work on Linux?
We do not expect many Linux-isms in the code, so it should be easy to port Mono to other UNIX variants.
What operating systems/CPUs do you support?
Please see the Supported Platforms page.
Does Mono run on Windows?
Yes. You can get pre-compiled binaries from the download page.
What is WAPI?
WAPI stands for Windows API.
For portability reasons, Mono uses Win32 APIs for I/O and related operations (semaphores, process creation, etc). You can find the Unix versions of these Win32 APIs in mono/mono/io-layer.
So on Windows, Mono directly uses Win32, while on Unix Mono uses Win32 APIs implemented in the io-layer.
This was necessary because many of the System.IO, etc. APIs have “Win32-isms” which prevent direct Unix implementation.
Part of the wapi implementation is per-user shared-data, stored in ~/.wapi
. This holds process IDs of mono processes, file share information (so opening a file opened for exclusive read can be denied), and other assorted information.
Deleting this shared data can have bad effects on mono applications. :-)
Will I require Cygwin to run Mono?
No. Cygwin is only required to build Mono.
How can I make calls to WindowsPrincipal.IsInRole () work on Linux?
If you have an application that makes a call like this:
bool allowed = WindowsPrincipal.IsInRole ("USAGNT\\UGR_RBP");
To make this work on Unix, you have to add a Unix group to the system, and list all the users that are to participate in this role, this can be done by adding the following line to /etc/group:
USAGNT\UGR_RBP:x:300:miguel,don,jon,julia
Where each of the users that belong to the group are added there.
Will Mono depend on GNOME?
It will depend only if you are using a particular assembly (for example, for doing Gtk# based GUI applications). If you are just interested in Mono for implementing a ‘Hello World Enterprise P2P Web Service’, you will not need any GNOME components.
Reusing Existing Code
Will I be able to use Microsoft SQL Server or will I need to switch to a specific Open Source Database. Will I need to recode?
There is no need to rewrite your code as long as you keep using Microsoft SQL Server. If you want to use an open source database, you might need to make changes to your code.
What do I need to watch out for when programming in VB.NET so that I’m sure to be able to run those apps on Linux?
Not making any P/Invoke or DLL calls should and not using anything in the Microsoft namespaces should suffice. Also do not use any Methods/Classes marked as “This type/method supports the .NET Framework infrastructure and is not intended to be used directly from your code.” even if you know what these classes/methods do.
Will built-in reporting be supported for crystal reports?
Crystal Reports are proprietary. Someone may try to emulate the behavior, but no-one has yet volunteered.
What about writing to the registry? As I understand it, Linux does not have a counterpart to the registry. Should I avoid relying on that feature?
Try to avoid it. Although there would be a emulation for registry in Mono too. GNOME does have a registry like mechanism for configuration. But Even if gnome has a configuration system similar to the registry, the keys will not be equal, so you will probably end up having to do some runtime detection, and depending on this load an assembly that has your platform-specific hacks.
System.Data.SqlClient with FreeTDS, will you port parts of these to C# and use them?
This has been done. System.Data.SqlClient is a fully managed provider for Microsoft SQL Server 7, 2000, and 2005 databases written in 100% C#. It used FreeTDS and jTDS as resources.
Operating System Questions
Can I use signal handlers with Mono?
You can as long as you use the Mono.Unix APIs that provide a safe mechanism for signal delivery.
To use the Mono.Unix API, you should:
- Reference the Mono.Posix.dll assembly
- Create a UnixSignal instance for each signal that you want to handle
- Call WaitAny on the UnixSignal
Typically you would create a thread to wait for the UnixSignal deliveries, as UnixSignal can not be mixed with other WaitHandles.
For example:
// Catch SIGINT and SIGUSR1
UnixSignal[] signals = new UnixSignal [] {
new UnixSignal (Mono.Unix.Native.Signum.SIGINT),
new UnixSignal (Mono.Unix.Native.Signum.SIGUSR1),
};
Thread signal_thread = new Thread (delegate () {
while (true) {
// Wait for a signal to be delivered
int index = UnixSignal.WaitAny (signals, -1);
Mono.Unix.Native.Signum signal = signals [index].Signum;
// Notify the main thread that a signal was received,
// you can use things like:
// Application.Invoke () for Gtk#
// Control.Invoke on Windows.Forms
// Write to a pipe created with UnixPipes for server apps.
// Use an AutoResetEvent
// For example, this works with Gtk#
Application.Invoke (delegate () { ReceivedSignal (signal); }
});
UnixSignal is the supported mechanism in Mono for receiving signals as it will not interfere with the runtime and isolates the developer from the finer complexity of signal handling in Unix.
Can I set my own signal handler like I do in C?
In general, you should not use signal handlers with Mono. Signal handlers behave like new threads and execute within the context of the thread that receives the signal which makes them very error prone.
If you still need to use a signal handler here are some guidelines for how to do this, but keep in mind that this is an unsupported use of the runtime and that you might very well be facing bugs on your own.
You should keep in mind that all you can do in a signal handler is set a static variable, anything else will randomly corrupt the state of your application.
But to set the variable, you need need to ensure that the signal handler is JITed before the signal is actually delivered. You must ensure at startup that your application will call the signal handler to ensure that the code has been JITed in advance, and only then set the signal handler to point to it.
A sample program that uses signal handlers in this way is mono-service
you can browse the source code here.
How to open a link in the user’s browser?
See the Howto_OpenBrowser
Mono and GCC
Will you support running C code on the Mono VM?
C is going to be supported through the GCC CIL project that is underway, this code is now hosted on the GCC CVS repository.
Also, invoking existing C code from Mono is possible by using P/Invoke, the Platform Invocation services.
Will you support running C++, Managed C++, C++ CLI code on the Mono VM?
For more details see our C++ page.
I have a C++ library that I would like to call from Mono, what can I do?
There are a few possible approaches:
- Use a code generator such as SWIG that parses the C++ code and generates C wrapper functions and C# code which DllImports the C wrappers.
Pro: This permits use of C++ code from C# Con: Not terribly elegant; Extra layer of C code may impact performance.
- There was work on a WHIRL-to-IL compiler, which would compile C (and probably C++) into CIL which Mono could execute.
Long term solutions that require a lot of work might be possible:
- Modify GCC’s to produce CIL.
What is the WHIRL-to-IL tion for using C++ with Mono?
We are no longer considering WHIRL as an intermediate IR for supporting C and C++, instead its now possible to use GCC 4.0 internal representation to generate CIL code.
What about Managed C++?
Once a full translator for GCC exists, we are interested in looking at expanding the GCC frontends to include extensions for Managed C++.
Are you working on a GCC front-end to C#?
We are not working on a GCC front-end for C#.
What about making a front-end to GCC that takes CIL images and generates native code?
There is no active work on this area, but Mono already provides pre-compilation services (Ahead-of-Time compilation).
Mono and the Basic Language
Does Mono implement the Basic language?
An implementation of the VB.NET language is now available, to find out more about the current state of the compiler see the page on Basic.
What about VB6
Mono does not have current plans to implement VB6 at this point.
The major value of VB6 is reportedly its deep integration with COM-based controls which would not be available on Unix, and it seems to be generally accepted that the major value of VB6 is the availability of third party controls.
An effort to implement a full stack would probably require a COM-stack to be implemented and a way of running existing controls. A task that is outside the scope of Mono.
What about VBScript and VBA?
Those languages are simpler to implement due to the restricted dependency on external COM objects, but there are no plans at this point to implement them by the Mono team.
Performance
How fast is Mono?
We can not predict the future, but a conservative estimate is that it would be at least ‘as fast as other JIT engines’.
In general, it is hard to answer the question rating from zero to ten as on a typical application there are many elements involved:
- The quality of the generated code, this being a metric of the code generator and the optimizations implemented on it. You can read about some optimizations in Mono on the Runtime page.
- The maturity of the class libraries used by the application. Mono’s tuning of class libraries has been done in an as-needed basis, and not every class is at the same level of maturity.
- The host operating system: I/O benchmarks are dominated by the operating system specifics (file system performance, file system synchronization guarantees, micro kernel or not and so on).
- On Web applications and database applications, the configuration and tuning of the web server will play a dominant role, while Mono’s performance these days is no longer on the critical path.
The best thing to do is to test your application in Mono and identify if the performance of your application is good enough in Mono.
Can you compare Mono performance with other languages/platforms?
The folks at the Language Shootout compare Mono’s performance with other platforms.
Do you track Mono’s performance improvements?
See our Performance Testing page for more details on the tests that we are tracking on performance.
What kind of framework does Mono have for new optimizations?
Mono’s JIT engine has been recently re-architected, and it provides many new features, and layers suitable for optimization. It is relatively easy to add new optimizations to Mono.
Read the Runtime page for more details.
Are you working on improving Mono performance?
Optimization and performance are things that we keep in mind during the development of our software. We routinely implement code, profile it and tune it. This is an ongoing process in all of Mono.
How can I improve the performance of my application?
We have a number of recommendations in our Performance Tips page covering some common practices to improve the performance of your application.
Are there any advantages in the CIL byte code over Java bytecode?
The CIL has some advantages over the Java byte code: The existence of structs in addition to classes helps a lot the performance and minimizes the memory footprint of applications.
Generics in the CLI world are first-class citizens, they are not just a strong-typing addition to the language. The generic specifications are embedded into the instruction stream, the JIT uses this information to JIT a unique instances of a method that is optimized for the type arguments.
The CIL is really an intermediate representation and there are a number of restrictions on how you can emit CIL code that simplify creating better JIT engines.
For example, on the CIL, the stack is not really an abstraction available for the code generator to use at will. Rather, it is a way of creating a postfix representation of the parsed tree. At any given call point or return point, the contents of the stack are expected to contain the same object types independently of how the instruction was reached.
Does Mono support performance counters?
Yes, they are described in our Mono Performance Counters page.
Mono and Portable.NET
What are the differences between Mono and Portable.NET?
Most of Mono is being written using C#, with only a few parts written in C (The JIT engine, the runtime, the interfaces to the garbage collection system).
It is easier to describe what is unique about Mono:
-
An advanced native-code compilation engine: Both just-in-time compilation (JIT) and pre-compilation of CIL bytecodes into native code are supported.
-
A foundation for code optimization: The new code generator in Mono builds on the experience of our first JIT engine, and enables us to implement various advanced compiler optimization tricks. With an SSA-framework, plenty of new optimizations are possible. The current list of optimizations are: Peephole postpass, Branch optimizations, Inline method calls, Constant folding, Constant propagation, Copy propagation, Dead code elimination, Linear scan global reg allocation, Conditional moves, Emit per-domain code, Instruction scheduling, Intrinsic method implementations, Tail recursion and tail calls, Loop related optimizations, Fast x86 FP compares, Leaf procedures optimizations. SSA-based partial redunancy elimination.
-
A self-hosting C# compiler written in C#, which is clean, easy to maintain.
-
Mono has a complete C# 1.0 implementation and has been stress tested a lot more than Portable.NET’s compiler.
-
Generics support and complete C# 2.0 support.
-
A multi-platform runtime engine: both a JIT engine and an interpreter exist. The JIT engine runs currently on x86, PowerPC, S390, S390x, Sparc, x86-64, Itanium and ARM systems, while the interpreter works on x86, SPARC, ARM, s390, PowerPC, HP-PA and Alpha systems.
-
The JIT engine is written using a portable instruction selector which not only generates good code but is also the foundation to re-target the JIT engine to other systems.
-
Full support for remoting in the runtime.
-
The C# compiler, the JIT engine and the class libraries are mature enough that the whole system has been self-hosting since April 2002. This means that we develop Mono completely with itself at this point.
By forcing ourselves to use our own code to develop our tools, we bug fix problems rapidly, and the system is overall more robust and tested than if we did not.
-
Our class libraries are licensed under the terms of the MIT X11 license which is a very liberal license as opposed to the GNU GPL with exceptions, this means that Mono can be used in places where the GPL with exceptions is not permissible.
-
Mono has a complete Web Services stack: we implement ASP.NET web servers and web clients as well as implementing the Remoting-based SOAP infrastructure.
-
Remoting implementation: Mono has a complete remoting infrastructure that is used in our own codebase to provide added functionality and performance to our ASP.NET engine and more.
-
Mono’s C# compiler flags more errors and warnings on invalid C# code.
-
Mono’s C# compiler is a CLS consumer and producer, which means that it will enforce during development the CLS rules.
-
Mono’s C# compiler has strong error handling and has closer adherence to the specification with support for definite assignment (required to generate verifiable IL code).
-
Mono’s C# compiler is written in C# which is easier for new developers to come in and improve, fix and tune. The Mono C# compiler in C# is faster than their C-based compiler.
-
Mono has a complete Reflection and Reflection.Emit: these are important for advanced applications, compilers and dynamic code generation (Applications like IKVM and IronPython depend on this feature for example).
-
Mono has a complete managed XML stack: XML, XPath, XML Serializer, XML Schema handling are fully functional, feature complete and tuned for performance. In addition to the Microsoft API, mono ships with the Mono.Xml.Ext library that contains an XQuery/XPath2 implementations.
-
Mono has a complete cryptography stack: we implement the 1.0 and 1.1 APIs as well as using our fully managed stack to implement the SSL/TLS transports.
-
Extensive database support: Mono ships with database provides for Firebird, IBM DB2, Oracle, Sybase, Microsoft SQL Server, SQLite, MySQL, PostgreSQL, Ole DB and ODBC.
-
A more complete System.Drawing implementation, based on Cairo.
-
Mono includes LDAP support.
-
Mono has a larger community of active developers. Full time developer from companies (Xamarin) as well as volunteers from the community.
In general, Mono is more mature and complete since it has been used to develop itself, which is a big motivator for stability and correctness, while Portable.NET remains pretty much an untested platform.
Common Problems
I have a multi-threaded application, and I keep getting timeouts, what is happening?
For a complete explanation of the problem, see our article: ThreadPool Deadlocks
MONO_EXTERNAL_ENCODINGS
When I run an application, I get the following error message:
** Message: Bad encoding for '????'
Consider using MONO_EXTERNAL_ENCODINGS
This problem arises when you have files in your file system that Mono can not convert into Unicode. Mono uses the UTF-8 encoding for the filenames stored in your file system by default, because it is the universally accepted standard.
The problem typically arises when you transfer files that were stored on a system that used a different encoding. This might happen if you copy a backup from an older system that encoded filename is latin-1 encoding and your current system uses UTF-8 (Example: the old system probably had LANG set to “en_US” and the new system uses “en_US.UTF-8).
It is highly recommended that you fix the encoding of your filenames on your file system using a tool like convmv, a perl utility that lets you rename files from one encoding to another.
Alternatively, you can set the MONO_EXTERNAL_ENCODINGS variable, but this is not recommended. To use this set the MONO_EXTERNAL_ENCODINGS variable to a comma separated list of encodings that the Mono runtime should try to use when guessing the values encoded in a filename.
See the manual page for details on how Mono uses this variable.
The values allowed are those returned by “iconv –list”.
This is a sample:
export MONO_EXTERNAL_ENCODINGS="utf8:latin1"
Notice that in older versions of Mono, the error message had a typo, and said “MONO_EXTERNAL_ENCODING” instead of “MONO_EXTERNAL_ENCODINGS”
The problem with using MONO_EXTERNAL_ENCODINGS is that even if Mono will be able to parse your filenames, Mono will still store the filenames internall as Unicode. If you try to move, overwrite or do any other manipulation in the file Mono will transform the filename from Unicode to your native encoding and it might fail to find the file.
ICMP Ping throws an exception
I used Mono to create a small C# console application that uses the ICMP class from http://cpp.sourceforge.net/?show=17688 to ping a host.
ICMP ping = new ICMP();
ping.Open();
TimeSpan span = ping.Send("192.168.1.1", new TimeSpan(0,0,5));
Unfortunately there is an exception.
Unhandled Exception: System.Net.Sockets.SocketException: Access denied
in <0x000b8> System.Net.Sockets.Socket:.ctor (AddressFamily family, SocketType type, ProtocolType proto)
in [0x00004] (at cPing.cs:41) ICMP:Open ()
in [0x00007] (at Main.cs:14) MainClass:Main (System.String[] args
The same code works fine when run in Visual Studio 2005 Professional or Mono on Windows. It does not work on Linux because you must run as root in order send ICMP packets. The /bin/ping program runs on Linux with the setuid bit. To ping from a Mono program you may either P/Invoke /bin/ping or setuid root your Mono program (after undertaking a thorough security audit of the runtime, the class libraries and any third party libraries that are linked, of course).
Alternatively, if your Linux kernel supports the so-called Linux capabilities you can use the setcap
(part of the libcap
library) to set the raw networking capability on the mono binary. In order to do it you need to log in as root and issue the following command:
setcap cap_net_raw=iep /path/to/mono
Doing it does not give mono the same privileges as setting the uid bit on the binary - it merely lets the mono runtime construct raw ip packets which is needed for the ICMP ping to work.
How can I configure Web.config and an ASPX file to turn the trace on?
<configuration>
<system.web>
<trace
enabled="false"
requestLimit="10"
pageOutput="true"
traceMode="SortByTime"
localOnly="false"
/>
...
I never used pageOutput=”true”. If it doesn’t work you may set it to “false” and get the trace from Trace.axd.
SelectSingleNode and SelectNodes ignore the default namespace I set in XmlNamespaceManager and thus do not return the expected nodes
(It is also likely to happen that you do not pass the XmlNamespaceManager argument to SelectNodes and SelectSingleNode, though in such cases you will soon notice since it will cause an error saying that you need it.)
You can’t use the default namespace in XPath (see section 2.3 of the XPath specification for details). Thus code like below won’t work:
XmlNamespaceManager nm = new XmlNamespaceManager (nameTable);
nm.AddNamespace ("", "http://www.w3.org/1999/xhtml");
return node.SelectSingleNode ("/html/body/form", nm);
You need to set non-empty prefix to the namespace you want to map e.g.:
XmlNamespaceManager nm = new XmlNamespaceManager (nameTable);
nm.AddNamespace ("h", "http://www.w3.org/1999/xhtml");
return node.SelectSingleNode ("/h:html/h:body/h:form", nm);
Note that you don’t have to change the prefixes in queried documents. They have nothing to do with the registered prefixes in the argument XmlNamespaceManager.
_wapi_shm_semaphores_init problems
If you get an error message like this:
** (process:2473): CRITICAL **: _wapi_shm_semaphores_init: semget error: No
space left on device. Try deleting some semaphores with ipcs and ipcrm
It means that you have run out of semaphores.
Mono keeps a file in ~/.wapi tracking the semaphore usage and will clean it up on shutdown. But if Mono fails to shutdown properly (abnormal program termination) or if you delete the file that Mono uses to track this information, semaphores might leak.
This typically happens when Mono has not had a chance to cleanup (abnormal program termination, or if you have instructed Mono to use a different location for semaphores, using a chroot environment and then wiping it out).
You can use: ipcs -s to list all the semaphores, and you must manually remove them (using ipcrm). These semaphores typically look like this:
$ ipcs -s
------ Semaphore Arrays --------
key semid owner perms nsems
...
0x4d036b25 156139526 username 600 8
...
$
To delete use:
ipcrm -s NNNN
Where NNNN is the number of the semaphore.
How can I execute assemblies from shared folders in Windows?
Open up a SDK command prompt and execute the following command:
caspol -q -machine -addgroup 1 -url file://z:/* FullTrust -name "Z Drive"
Replace Z: with the drive (or path) where you have your shared folders.
To enable 1.1 assemblies you need to open a SDK 1.1 command prompt and to enable 2.0 assemblies you need to open a SDK 2.0 command prompt.
For more information see this: http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=1519
Credits
The FAQ contains material contributed by Miguel de Icaza, Jaime Anguiano, Lluis Sánchez, Niel Bornstein.