I’m quite well versed in C++ (and supporter of Boost, Loki and libsigc++ – see my C++/CLI string marshaler), but over time, I started using .NET more and more until I only resorted to C++ where absolutely required. That’s because .NET provides a much richer environment (Inversion of Control/ Dependency Injection containers like Ninject are well established here and unit testing and test coverage analysis are a breeze whereas most of the C++ world is still struggling to come to terms with these developments.
In this section, I posted some finished components for Mono and .NET which you can use freely. If not stated otherwise, all my code is licensed under the IBM Common Public License – meaning you can use it in any kind of application, statically link it and keep your own source code to yourself. The only requirement is that if you change my code, you make those changes available again (either right away or upon written request, your choice). I think that’s pretty fair :)
Short Primer on Mono/.NET
If you’re using visiting this page because you’re curious about Mono or .NET, here’s a short explanation about what .NET and Mono are about. It’s a bit like Java, but designed from scratch with the issues Java ran into over the years kept in mind and a lot of cool sauce added on top of it.
Let’s take a look at how programs are compiled by traditional compilers and by a .NET compiler.
Traditional software, written in a programming language like C or C++, is transformed from source code into machine code by a compiler, producing a so-called binary (usually with file extensions like .dll, .exe or .so).
This binary can then be run by the end-user as long as his CPU understands the machine code instructions and his operating system provides the external functions used.
Such binaries are bound to a single platform (= operating system and CPU architecture).
A Windows binary compiled for x64 CPUs won’t work on Linux. At least not
without some kind of emulation software that tries to simulate the platform expected by the
binary. Similarly, it will not work in x86 environments.
Source code written in a .NET enabled language is instead compiled to an intermediate format called CIL (Common Intermediate Language). This language is independent of any CPU architecture. Only when a CIL binary is executed does it get transformed into actual machine code by the platform’s .NET runtime.
This means that you can copy a CIL binaries to other computers running a 64 bit OS, Linux, MacOS or even your mobile phone. Their respective .NET runtime (eg. the Microsoft .NET Framework or Mono will generate suitable machine code in the instant you attempt to launch the program.
So as to not rely on external functions that are operating system specific, .NET defines an
extensive class library called the .NET Framework that interfaces with the underlying
platform and provides .NET programmers with a clean and unified interface. In other words,
a .NET program only interfaces with the .NET Framework and then the platform’s respective
implementation of the .NET Framework does the operations needed by calling into platform
Pros and Cons
Here is a short overview of the advantages and disadvantages of .NET as I see them:
Advantages of .NET
Since all .NET-enabled programming languages work through CIL, any .NET language can interface with any other .NET language.
No more wrapper-writing and searching for language bindings.
Thanks to Mono and other porting efforts such as DotGnu, software written in pure .NET can be run on many platforms as-is. In fact, any pure .NET 1.1 oder .NET 2.0 application can already be run under Linux without modifications.
Once compiled, a .NET assembly (the .NET equivalent of a .dll/.so) is self-describing. Just reference a .NET assembly in your project and you will have access to all its exposed classes.
No more hazzle with headers, DLL import libraries and compiler options anymore.
Drawbacks of .NET
Slower Application Start
Applications written in .NET usually take longer to start than native applications. Doing actions for the first time will also feel slower than normal because the JIT compiler will have to compile the code being called first. This can be avoided by pre-compiling an application when it is installed.
.NET programs can easily be decompiled into code that very closely resembles the original code minus its comments. Therefore, IP theft and undesirable modification of an executable to circumvent protection measures or to cheat is easily possible. Using a code obfuscation tool can make the decompiled code much harder to read but makes updated and patches difficult.
Once in a while, the .NET garbage collector will kick in to reclaim unused memory and to compact used memory into a contiguous block. During this time, an application is essentially frozen. Garbage collections take just a few milliseconds, but for games this means that the player will experience a slight jerk in the game. Depending on how carefully a game is designed, this may happen every few minutes or every two seconds.
.NET is much more fun to work in because of the well organized .NET Framework, because you can package your classes in neat assemblies and no longer have to worry about making sure the header version matches the library, using the right runtime library, static or dynamic binding, 32 bit or 64 bit builds or even which operating system you’re targeting.
Modern language features such as reflection (introspection) and dynamic code generation allow you to use powerful programming techniques such as unit testing, creating dynamic mocks, measuring test coverage and managing your dependencies with an inversion of control container. In C++, only unit testing is marginally supported.
Native code gives you more control and has many more established libraries doing all kinds of things from image processing to video decoding to physics simulation. Lots of libraries are being ported to or wrapped in .NET, but until libraries emerge that are written in .NET and for .NET, these will always be second-class interfaces that lag behind their native counterparts.