This article was written from my experiences of working with version 3 of the .Net Micro Framework. Version 4 is now out and promises much – to the best of my knowledge this article is still relevant, but is as yet untested.
So you’ve been working on the .Net Micro Framework for a while. Recently you’ve added a couple of new classes to your project, implemented some new functionality and now it doesn’t compile. Your code has no syntax errors yet when you attempt to compile you get a strange non-descript build error:
The error gives no line of code to look at and the file it references isn’t something you recognise in your project –therefore it doesn’t appear to be a problem with your code, so what’s wrong?
This is one of several particularly unhelpful compile errors you can encounter from time to time when developing for the .Net Micro Framework. To find out more you need to do a little digging…
If you switch to the Output window and review the Build Output you will quickly notice an error that looks something like this:
The first thing you should notice here is that the window appears to successfully compile the project with ‘0 errors & 0 warnings’. Why then does it ultimately fail?
Understanding .Net Micro Framework compilation:
Like regular .Net projects the .Net Micro Framework compilation process is a two stage process.
First the standard C# compiler (csc.exe) is called to compile the project into MSIL, just like any regular .Net assembly. What happens next is where the Micro Framework differs from it’s older brother; Micro Framework applications are not JIT compiled at runtime instead they are optimized at compile time by a tool called the Meta Data Processor. This optimised code is then interpreted at runtime.
The Meta Data Processor performs two functions.
1. Optimise the MSIL for the purpose of size.
Our desktop machines may think nothing of an executable that is 10 MB in size but Micro Framework enabled devices are not likely to have much more than 1MB of space to store and run your application.
2. Optimise the code to use less runtime resources (RAM, etc).
This applies various techniques such the use of a shared string table that stores class member information, text values and other common meta data used by the application.
Part of the optimisations above includes applying some hard internal limits to your applications. This is usually the cause of the above error. To see the more details of the compile error you need to run the MetaDataProcessor in the command prompt using the same arguments that caused it to fail.
You can copy the full command string (this is usually quite large) from the Build Output window (above) and paste it into your command prompt window and run it. The command prompt output should show you the same error but with greater detail:
In this case the maximum size of the shared string table had been exceeded.
The solution itself is fairly simple. These limits are on a per project/assembly basis. So to get around this problem all you need do is split your code into multiple projects. This is usually not too difficult and now that you are aware of these limitations you can start to plan ahead as you build your software project.
Other known Meta Data Processor Errors:
There are several other errors generated by the Meta Data Processor while optimising your code. These are not yet in any form of online documentation (at least none that I could find) that I have read. As a rule every one of these can be resolved by splitting up the project into multiple smaller components.
CLR_E_OUT_OF_RANGE: maximum size of stream ‘ByteCode’ – The Micro Framework executable (.pe) files are limited to 65kb of optimised IL code each.
CLR_E_OUT_OF_RANGE: maximum size of stream ‘MethodDef’ – The number of methods defined in your assembly has exceeded the internal limit.
Of course, now that the latest version of the Micro Framework (including the Meta Data Processor) has been made open source the task of hunting down the cause of these errors should be much simpler.
Author: Gavin Osborn