Building and using C++ WinRT components
Written by Mike James   
Monday, 10 October 2011
Article Index
Building and using C++ WinRT components
Using the CX componenent

WinRT Components are COM made friendly. Here we demonstrate how to create a trivial C++ CX, i.e. a native WinRT component and how to use it in each of the languages - C#, Visual Basic, JavaScript and C++.

 

One of the big changes introduced with WinRT is the use of an object-oriented API. The objects in question are WinRT components and they are based on COM technology. This must mark one of the biggest turnarounds in recent computing. After spending so long developing COM, Microsoft all but abandoned it for .NET and managed code. Now COM is back and so are many of the old ways of doing things.

There are some good things about this situation.

In particular there's the fact that we now have an object-oriented Windows API, even if it is a little underdeveloped at the moment. It is also possible to extend the API by creating new WinRT components.

You can use C++ to create native WinRT components and these are first-class components in the sense that they are compiled to native code and are implemented as COM objects.  Recently introduced is the ability to create managed WinRT components using C++ or VB .NET. These managed WinRT components make use of COM interop and are simply managed code objects with a COM wrapper that makes them usable as WinRT components.

So if you want the best performance and the ability to call the old Win32 API you need to implement C++ WinRT components, also known as C++ Component Extensions or C++ CX.

In this article we are going to demonstrate how to create a trivial C++ CX, i.e. a native WinRT component and how to use it in each of the languages - C#, Visual Basic, JavaScript and C++.

If the thought of having to go back to COM makes you feel slightly ill then the final good news is that WinRT Components are easy to create and use. In fact they are modeled on the way CLI components are created and in this sense COM has at least learned some from the .NET adventure.

So WinRT Components are COM made friendly. Let's see how friendly by implementing a component and using it in C#, VB .NET and JavaScript.

Meet the C++ CX

If you have the developer preview of Windows 8 installed then you can try out building and using yoru own WinRT Component.

Start VS Express 11 running and create a new Visual C++ WinRT Component DLL project called MyWinRTComp.

The template creates a basic WinRT Component for you with a property, a method and an event - just to show you how they work. Within the private parts of the component you can simply write standard C++ and there is nothing extra to learn. In the public parts of the component you have to use WinRT data types. This is because the public parts of the component correspond to the COM interface and hence modified COM data types are in use.

The simplest thing to do at this stage is not to change the generated code but to examine it to see how it works and then try it out in the other languages. If you read the code, you will find that your component has been declared as a simple class:

public ref class WinRTComponent sealed
{

The only new feature is the use of ref to indicate that this is a COM component.

To provide an example of how to create a component there is a sample property:

int _propertyAValue;
public:
property int PropertyA
{
int get() { return _propertyAValue; }
void set(int propertyAValue)
{ _propertyAValue = propertyAValue; }
}

and an example method:

int Method(int i);

which in the implementation simply returns i and an event:

 event SomeEventHandler^ someEvent;
};

Putting the whole lot together gives:

public delegate void SomeEventHandler(int i);

public ref class WinRTComponent sealed
{
int _propertyAValue;
public:
WinRTComponent ();
~WinRTComponent ();

property int PropertyA
{
int get() { return _propertyAValue; }
void set(int propertyAValue)
{ _propertyAValue = propertyAValue; }
}

int Method(int i);

event SomeEventHandler^ someEvent;
};

Notice that there is a stub constructor and destructor and the event has to be declared as a delegate. In case you haven't used Visual C++ recently, delegate was introduced as part of the non-standard extensions to create Managed C++. Many of the Manged C++ extensions have been reused to connect to the COM infrastructure - for example the get/set property type. Notice that COM only allows methods as part of an object and so you have to use a get/set property rather than a simple public field. If you are puzzled about the use of the ^ operator then it is another CLR addition and it is just a special type of pointer introduced to deal with pointing at managed objects which now points at COM objects instead. 

This is all we need to try things out. Build the project and as long as there are no errors, there shouldn't be, then the WinRT component is ready for us to use.

Using the component from C#

All you have to do to make use of the new WinRT component from C# is to add a reference to the project. Start a new C# Metro application. Next right click on References in the Solution Explorer and select Add Reference. Next click Browse and navigate to the Debug directory of the MyWinRTComp project and select the MyWinRTComp.winmd file. Also add

using MyWinRTComp;

so that you can use short names for everything.

First we instantiate the WinRTComponent:

WinRTComponent MyObject = 
new WinRTComponent();

Although this looks like a standard .NET object creation, it actually creates a COM object. All of the complexities of COM are hidden from you.

Once you have an instance you can make use of it as if it was a perfectly normal C# .NET object:

MyObject.PropertyA = 1;
int temp = MyObject.PropertyA;
temp = MyObject.Method(1);
MyObject.someEvent +=
new SomeEventHandler((t) => { });

At this point things should just work but there is a minor glitch in the pre-beta software and you also have to manually add a reference to platform.winmd that you will find in C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\.



Last Updated ( Friday, 14 October 2011 )