Developing software for Windows Phone always meant developing managed code. Whether it was traditional development in Silverlight to create your apps or if you decided to build games in XNA, you never left the cozy world of a managed runtime environment. While usually this is something that gives you much more benefits than drawbacks, there are situations where having the possibility to use unmanaged code would be very desirable. Unfortunately, until now using managed code was not a conscious decision you could make as the developer, but rather a limitation of the platform that was imposed on you, and a choice that you didn't have.
With version 8 of Windows Phone, Microsoft opens up the platform to unmanaged third party code and allows you to develop in C++. I have hinted at this in the first part of the series already when I presented you the simplified overview of the new platform infrastructure:
As you can see, traditional developing in .NET (or, as it was called back then, Silverlight :)) is only one of the available options. We now have a whole set of native APIs at hand that we can also use, and we are free to choose whatever programming model matches our situation and requirements best.
Making the Decision
When I ask people in my workshops and trainings about what they think should be driving reasons behind using native code as opposed to managed code, 90% of the time the first answer that is mentioned is "performance". Up to this day, developers still think of performance as the primary motivation why someone should choose native development over let's say writing the same in C#. The interesting part for me is that apparently the background of a developer doesn't seem to influence that very much. Not only people you'd expect to come up with these arguments (with a background in C++ development for example) think that, but also junior developers who never ever had to write or use native code in a real project. Of course it's true that managed code takes a performance penalty, and there are scenarios where this actually is the decisive argument. However, the truth is that developers very often overestimate the performance benefit they receive from using native code. I often do code reviews and analyses of applications, and usually bad performance is the result of things that are not tied to managed code or the underlying runtime, but rather flaws of the involved architecture and software design. Rethinking your software's structure is in almost all cases what you need to do, and only switching to a different programming model wouldn't result in any measurable improvements. So if you think that support for native code in Windows Phone means you now should rewrite your existing C# projects in C++ to get an enormous boost in performance, please think again – that is definitely not what you're supposed to do, and it definitely will result in a huge disappointment.
With this out of the way, you may ask yourself what valid reasons to go native actually are? Well, here is my personal list of considerations, ordered by descending priority. Yours of course may differ, but in the end it more or less always comes down to variations of these.
- Reusability: You have some legacy code around that you really don't want to rewrite but still use in your app.
- Portability: You want to use the code you're about to write on multiple platforms.
- Personal Preference: You are a developer who really favors C++ over e.g. C# or you have significantly better skills in C++.
- Performance: You really are in need for these last bits of performance benefits and know what you're doing.
Now that we have talked about the whys, it's about time to get into the details of how you use native code.
A Closer Look at What's Available
First of all, let's take take a look at the options we have in Visual Studio. When you inspect the available templates for Windows Phone and C++, you can see that the ones that create new applications are very much focused on Direct3D:
Surprisingly, creating a "Direct3D with XAML" C++ application actually creates a C# main project and a separate Windows Runtime Component in C++. The basic idea here is very similar to how you mixed XNA and Silverlight in Windows Phone 7: Silverlight did take the leading role there and allowed you to embed XNA on individual pages. With the mentioned template in Windows Phone 8, the main application is based on .NET for Windows Phone and makes use of specific controls in XAML (in particular the DrawingSurfaceBackgroundGrid) to embed Direct3D in a similar way. The actual rendering in the sample then is handed off to the native component. This mixture of technologies probably is the typical use case: it allows you to benefit from both the flexibility and comfort of XAML with managed code (for example for menus and other details) as well as the power of native code at the same time.
If you want to create an app that really has no connection to C# and managed code anymore, you can select the second template that already has the "native only" reference in its name, which then results in a pure unmanaged application. The other available C++ templates are there to create libraries, either native ones that are dynamically or statically linked, or single Windows Phone Runtime Components which we now will take a closer look at.
It's All About Communication
For interop and communication between the managed and unmanaged world, just like in Windows 8, the Windows Runtime is the magic glue that allows you to let different technologies interact with each other in a very natural way. Particularly, we can integrate unmanaged C++ implementations into managed apps by creating simple Windows Runtime wrappers. They can easily be consumed from C# and feel very ".NET-like".
It's really not obvious you're not using normal .NET classes and objects when you interact with WinRT components, because you don't have to resort to traditional ways of interop or COM communication for that.
A Practical Sample
I want to show you an example of how you can easily integrate an existing C++ code base in your managed C# app by making use of such a Windows Runtime Component. First of all, since the C++ app templates very much focus on Direct3D, I create a new C# XAML application instead.
Then, in a second step, I simply add another project to my solution, but this time I choose the C++ "Windows Phone Runtime Component" template. After the project is created, I add a reference to it to the main project.
As you can tell from the names in the screenshots, I'm going to re-use an existing Mandelbrot algorithm that is written in C++. The motivation behind this could be any of the above mentioned reasons: in my case I found some existing code and I'm simply reusing it for demonstration. But it could very well be a particularly fast algorithm I want to integrate, or some code that I want to share between multiple platforms.
The code of the Windows Phone Runtime Component is explained easily:
In line 3, I include the header file for the existing native implementation that I want to use. In line 13, I declare a member for that legacy type that I can then use later on. These two things could be part of any other C++ code and are not particularly interesting.
The details that are special to Windows Runtime Components however are highlighted in line 7 and line 11. First, the class needs to be decorated with the "ref" keyword as well as be a sealed class. The first one tells the compiler that this is a WinRT class that needs to be treated in a special way, the latter one simply is a technical restriction for these kinds of components. In line 11 you can see a wrapper method that I introduced and that will do nothing else but invoke the legacy implementation contained in the "Mandelbrot" class (see below). However, the argument types need some comments. As you can see, I'm using a "WriteOnlyArray", which is a special type that determines that the native code will be able to write to the array. The type is followed by a hat symbol (^) that may remind you of managed C++ (which this isn't!). This is the notation for WinRT types that are automatically reference counted.
Obviously, when I pass on the call to the original native implementation, I cannot use the WinRT types, because that old code knows nothing about those. Instead, I use the "Data" member to access the underlying type that my legacy code expects and understands (here: double*):
That's basically all you have to do:
- Create wrapper methods for all the functionality you want to expose
- Make sure you only use compatible WinRT types in the public API of your component
For the latter one, you should take a look at the available documentation for proper type mapping [1], and of course the compiler will also hint you at errors in your code.
Consuming WinRT Components From C#
As mentioned before, the consuming end of this feels very natural to managed developers. You simply have to add a reference to the project containing your Windows Runtime Component and then can start using your component right away:
The first highlighted line (1.) creates a new instance of the Windows Runtime component, the second marked line (2.) invokes the wrapper method which internally in turn invokes the original native implementation. As you can see, there's virtually no difference to how you would use normal .NET types – this is the magic of WinRT's projection layers that translate everything into natural .NET types behind the scenes for you.
In the sample, I continue to convert the result of the native call to a WriteableBitmap which then is displayed on the XAML page. Et voilà, we have a Mandelbrot set in our managed application, coming straight out of a ten year old piece of native C++ code:
Limitations And Opportunities
One thing to note is that obviously you cannot use native code which has dependencies on particular, incompatible features that are not available on Windows Phone. This somewhat limits the possibilities to reuse existing legacy code especially if it is not designed very well. However, the ability to use native code now also opens a lot of new opportunities that simply weren't possible before. For example, it's now much easier to bring interesting projects like the Unity 3D engine over to the platform [2], which in turn will make it more attractive for developers too.
I hope you enjoyed this quick detour to native development and how you can benefit from it on Windows Phone 8. The sample code may be downloaded at the top of this article.
Have fun!