Tuesday, January 7, 2014

Windows Phone Natives - How to Leverage Native Code on Windows Phone

With Windows Phone 8 the possibility to use native code for development was introduced to the public SDK. It's a powerful feature and it can help to improve the performance for certain heavy computing tasks, reduce the memory footprint or just to leverage certain APIs which are only available in native code. Media Foundation or Direct3D for example are native only, but it could as well be a proprietary library from another third party written in C/C++.
In order to use native code on Windows Phone one has to write a native Windows Phone Runtime Component (WinPRT). Such a WinPRT library encapsulates the native code internally and only exposes WinRT types, therefore it can be consumed through the WinMD projections also in managed C# projects.

This blog post provides an introduction with an easy sample to get started. The MSDN also provides a very good Windows Phone native code overview, a list of the available Win32 and COM APIs on Windows Phone including an index of all supported Win32 functions. It contains such important things like the native sockets API Winsock, the National Language Support (NLS) functions for all things around region, language and culture and much more native APIs.

How it works

  1. First of all you need to create a Windows Phone App 8 project with Visual Studio.

  2. Then add a new Visual C++ Windows Phone Runtime Component (WinPRT) project to the solution.


  3. Now you need to add the solution's WinPRT project as reference to the App project. Note that Visual Studio will automatically take care of adding the required ActivatableClass definition to your consuming App project. Refer to this if you ever need to add a WinRT component manually to another project.

  4. Open the generated precompiled header file pch.h and add an include for windows.h:
    // pch.h - Header for standard system include files.
    #pragma once
    
    #include <windows.h>

    For this sample we use the Win32 function IsProcessorFeaturePresent to query if certain processor features are supported. This function is defined in windows.h.

  5. Open the header file of your component (ProcessorInfoComponent.h) and add the method declaration of IsNeonSupported to our WinPRT component which will internally use the IsProcessorFeaturePresent, but only expose a WinRT bool type. The MSDN has a nice Quick Reference which provides a table how Standard C++ types and constructs map to C++/Cx WinRT.
    namespace ProcessorInfoComponent
    {
        public ref class ProcessorInfoProvider sealed
        {
        public:
           bool IsNeonSupported();
        };
    }

  6. Open the source file (ProcessorInfoComponent.cpp) and add the method implementation to our WinPRT component which will call IsProcessorFeaturePresent and return the result.
    The IsNeonSupported wrapper method here will provide the information if the processor supports the ARM VFP/Neon: 32 x 64bit register bank. There are many other queryable parameters available beside PF_ARM_VFP_32_REGISTERS_AVAILABLE used here. Those are defined in winnt.h and partly documented at the MSDN.
    #include "ProcessorInfoComponent.h"
    using namespace ProcessorInfoComponent;
    
    bool ProcessorInfoProvider::IsNeonSupported()
    {
       return IsProcessorFeaturePresent(PF_ARM_VFP_32_REGISTERS_AVAILABLE);
    }

  7. You are now ready to use the component in your managed C# code.
    private void Button_Click(object sender, RoutedEventArgs e)
    {
       var infoProvider = new ProcessorInfoComponent.ProcessorInfoProvider();
       var hasNeon = infoProvider.IsNeonSupported();
    
       Info.Text = string.Format("Is ARM Neon supported: {0}", hasNeon);
    }
The complete sample solution can be downloaded here.
If you run the sample in the emulator you will see IsNeonSupported() returns false, since it's running on the x86 CPU, but if you execute the sample on a device IsNeonSupported() should return true. Keep in mind you are now using native code so you have to compile a build for ARM (device) or x86 (emulator). AnyCPU won't work anymore.

The presented is just a very easy sample but it already shows how native code on Windows Phone can help you to access information not available otherwise.

No comments:

Post a Comment