Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Cross-platform Development – Lessons Learned from Banshee/Mono

Cross-platform Development – Lessons Learned from Banshee/Mono

This item in japanese

In a Scott Hanselman interview, Aaron Bockover of Novell talks about the challenges to create Banshee, a cross-platform application built in C# on Mono for Linux, Max OS X and Windows.

Banshee was started by Aaron back in 2005 to create a media player for the Linux platform. Built on Mono, it ended up being a cross-platform application running on Linux, Mac OS X (starting with v. 1.4) and by the end of this summer on Windows. The application already builds and runs on Windows, but there are some things to be fixed before going public.

One of the purposes building Banshee was to showcase building an application on Mono. The project started when Mono was in its incipient phase and not many believed in it. Other similar applications are: F-Spot, a photo management application, and Tomboy, a note taking application. 

Not only Banshee benefited from being built on Mono, but Mono itself evolved and got problem fixes spotted while developing the media player, so the end result was strengthening Mono. An example was Banshee being the first project to use generics when they were introduced in Mono’s C# compiler, and in the process some bugs were uncovered in the compiler that were later fixed.

Mono’s compiler, garbage collector, and JIT were not written by porting .NET code to Linux, but by rewriting all the code starting from specifications. The .NET libraries were written based on their public API as documented by Microsoft. The end result is generating MSIL bytecode that runs on any platform, Windows, Linux, Max OS. The compatibility goes so far that any existing bugs in the .NET framework must be duplicated by Mono in order to guarantee the same code path followed by an application when running on different platforms. This cross-platform approach raises many difficulties, a major one being file access. When programming in Mono, the developer is not aware which file system his application will be using, a POSIX one, or a FAT or NTFS one. Mono has multiple implementations of the System.IO library in order to make it work.

A detail is the implementation of System.IO.Directory.GetFiles() which returns an array. The caller needs to wait until the method builds the entire array and returns. That induces a performance penalty when the directory happens to contain lots of files. To circumvent that, the developer has the option to use the Mono.Posix library to discover the files in a directory, a method which returns an IEnumerable, being much faster to find the desired file.

Banshee uses an IO abstraction layer which defaults to System.IO to make it work across all platforms, but when the application discovers a POSIX system, it uses the Mono.Posix library which has better performance.

There are two kinds of abstraction layers: a hardware one, and its necessity is obvious, then there is a platform abstraction layer to make use of the best features a platform provides. An example is the abstraction layer for  GNOME, which can stop the screen saver interfering with an application, built on a feature offered by the desktop environment. For platforms not implementing a specific must-have feature, Mono implements it in extension libraries, one for each platform. Such Mono libraries, extending Mono.Addins, can be used by .NET developers working in Visual Studio without having to run the code on Mono, because the libraries are adds-on that can be used independently.

Mono applications, like Banshee, detect the platform they are running on at build time. The building procedure creates the core components and the necessary add-ins based on the platform the application is supposed to run on. On Windows, all the necessary information is saved in the solution file opened with Visual Studio and all necessary DLL are added during built. Nothing particular to Linux goes into a Windows build. Linux builds are done a Linux machine, while Windows ones on a Windows PC. Platform detection at runtime can be done, and it is done in specific cases, but it is not recommended.

Rate this Article