April 2013
Volume 28 Number 04
Component Extensions - A Tour of C++/CX
By Thomas Petchel | April 2013
Ready to write your first Windows Store app? Or have you already been writing Windows Store apps using HTML/JavaScript, C# or Visual Basic, and you’re curious about the C++ story?
With Visual C++ component extensions (C++/CX), you can take your existing skills to new heights by combining C++ code with the rich set of controls and libraries provided by the Windows Runtime (WinRT). And if you’re using Direct3D, you can really make your apps stand out in the Windows Store.
When some people hear about C++/CX they think they have to learn a whole new language, but the fact is that for the vast majority of cases you’ll be dealing with just a handful of nonstandard language elements such as the ^ modifier or the ref new keywords. Furthermore, you’ll only use these elements at the boundary of your app, that is, only when you need to interact with the Windows Runtime. Your portable ISO C++ will still act as the workhorse of your app. Perhaps best of all, C++/CX is 100 percent native code. Although its syntax resembles C++/Common Language Infrastructure (CLI), your app won’t bring in the CLR unless you want it to.
Whether you have existing C++ code that was already tested or just prefer the flexibility and performance of C++, rest assured that with C++/CX you don’t have to learn a whole new language. In this article you’ll learn what makes the C++/CX language extensions for building Windows Store apps unique, and when to use C++/CX to build your Windows Store app.
Why Choose C++/CX?
Every app has its own unique set of requirements, just as every developer has his own unique skills and abilities. You can successfully create a Windows Store app using C++, HTML/JavaScript or the Microsoft .NET Framework, but here are some reasons why you might choose C++:
- You prefer C++ and have existing skills.
- You want to take advantage of code that you’ve already written and tested.
- You want to use libraries such as Direct3D and C++ AMP to fully unleash the hardware’s potential.
The answer doesn’t have to be one or the other—you can also mix and match languages. For example, when I wrote the Bing Maps Trip Optimizer sample (bit.ly/13hkJhA), I used HTML and JavaScript to define the UI and C++ to perform the background processing. The background process essentially solves the “traveling salesman” problem. I used the Parallel Patterns Library (PPL) (bit.ly/155DPtQ) in a WinRT C++ component to run my algorithm in parallel on all available CPUs to improve overall performance. This would have been difficult to do from just JavaScript alone!
How Does C++/CX Work?
At the heart of any Windows Store app is the Windows Runtime. At the heart of the Windows Runtime is the application binary interface (ABI). WinRT libraries define metadata through Windows metadata (.winmd) files. A .winmd file describes the public types that are available, and its format resembles the format that’s used in .NET Framework assemblies. In a C++ component, the .winmd file contains only metadata; the executable code resides in a separate file. This is the case for the WinRT components that are included with Windows. (For .NET Framework languages, the .winmd file contains both the code and the metadata, just like a .NET Framework assembly.) You can view this metadata from the MSIL Disassembler (ILDASM) or any CLR metadata reader. Figure 1 shows what Windows.Foundation.winmd, which contains many of the fundamental WinRT types, looks like in ILDASM.
Figure 1 Inspecting Windows.Foundation.winmd with ILDASM
The ABI is built using a subset of COM to enable the Windows Runtime to interact with multiple languages. In order to call WinRT APIs, the .NET Framework and JavaScript require projections that are specific to each language environment. For example, the underlying WinRT string type, HSTRING, is represented as System.String in .NET, a String object in JavaScript and the Platform::String ref class in C++/CX.
Although C++ can directly interact with COM, C++/CX aims to simplify this task through:
- Automatic reference counting. WinRT objects are reference-counted and typically heap-allocated (no matter which language uses them). Objects are destroyed when their reference count reaches zero. The benefit that C++/CX offers is that the reference counting is both automatic and uniform. The ^ syntax enables both of these.
- Exception handling. C++/CX relies on exceptions, and not error codes, to indicate failures. Underlying COM HRESULT values are translated to WinRT exception types.
- An easy-to-use syntax for consuming the WinRT APIs, while still maintaining high performance.
- An easy-to-use syntax for creating new WinRT types.
- An easy-to-use syntax for performing type conversion, working with events and other tasks.
And remember, although C++/CX borrows the C++/CLI syntax, it produces pure native code. You can also interact with the Windows Runtime by using the Windows Runtime C++ Template Library (WRL), which I’ll introduce later. However, I hope that after using C++/CX you’ll agree it makes sense. You get the performance and control of native code, you don’t have to learn COM and your code that interacts with the Windows Runtime will be as succinct as possible—letting you focus on the core logic that makes your app unique.
C++/CX is enabled through the /ZW compiler option. This switch is set automatically when you use Visual Studio to create a Windows Store project.
A Tic-Tac-Toe Game
I think the best way to learn a new language is to actually build something with it. To demonstrate the most common parts of C++/CX, I wrote a Windows Store app that plays tic-tac-toe (or depending on where you grew up, you might call it “noughts and crosses” or “Xs and Os”).
For this app, I used the Visual Studio Blank App (XAML) template. I named the project TicTacToe. This project uses XAML to define the app’s UI. I won’t focus much on the XAML. To learn more about that side of things, see Andy Rich’s article, “Introducing C++/CX and XAML” (msdn.microsoft.com/magazine/jj651573), in the 2012 Windows 8 Special Issue.
I also used the Windows Runtime Component template to create a WinRT component that defines the logic of the app. I love code reuse, so I created a separate component project so that anyone can use the core game logic in any Windows Store app using XAML and C#, Visual Basic, or C++.
Figure 2 shows what the app looks like.
Figure 2 The TicTacToe App
When I worked on the Hilo C++ project (bit.ly/Wy5E92), I fell in love with the Model-View-ViewModel (MVVM) pattern. MVVM is an architectural pattern that helps you separate the appearance, or view, of your app, from its underlying data, or model. The view model connects the view to the model. Although I didn’t use full-on MVVM for my tic-tac-toe game, I found that using data binding to separate the UI from app logic made the app easier to write, more readable and easier to maintain in the future. To learn more about how we used MVVM in the Hilo C++ project, see bit.ly/XxigPg.
To connect the app to the WinRT component, I added a reference to the TicTacToeLibrary project from the TicTacToe project’s Property Pages dialog.
By simply setting the reference, the TicTacToe project has access to all of the public C++/CX types in the TicTacToeLibrary project. You don’t have to specify any #include directives or do anything else.
Creating the TicTacToe UI
As I said earlier, I won’t go much into the XAML, but in my vertical layout, I set up one area to display the score, one for the main play area and one to set up the next game (you can see the XAML in the file MainPage.xaml in the accompanying code download). Again, I used data binding pretty extensively here.
The definition of the MainPage class (MainPage.h) is shown in Figure 3.
Figure 3 The Definition of the MainPage Class
#pragma once
#include "MainPage.g.h"
namespace TicTacToe
{
public ref class MainPage sealed
{
public:
MainPage();
property TicTacToeLibrary::GameProcessor^ Processor
{
TicTacToeLibrary::GameProcessor^ get() { return m_processor; }
}
protected:
virtual void OnNavigatedTo(
Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
private:
TicTacToeLibrary::GameProcessor^ m_processor;
};
}
So what’s in MainPage.g.h? A .g.h file contains a compiler-generated partial class definition for XAML pages. Basically, these partial definitions define the required base classes and member variables for any XAML element that has the x:Name attribute. Here’s MainPage.g.h:
namespace TicTacToe
{
partial ref class MainPage :
public ::Windows::UI::Xaml::Controls::Page,
public ::Windows::UI::Xaml::Markup::IComponentConnector
{
public:
void InitializeComponent();
virtual void Connect(int connectionId, ::Platform::Object^ target);
private:
bool _contentLoaded;
};
}
The partial keyword is important because it enables a type declaration to span files. In this case, MainPage.g.h contains compiler-generated parts, and MainPage.h contains the additional parts that I define.
Notice the public and ref class keywords in the MainPage declaration. One difference between C++/CX and C++ is the concept of class accessibility. If you’re a .NET programmer, you’ll be familiar with this. Class accessibility means whether a type or method is visible in metadata, and therefore accessible from external components. A C++/CX type can be public or private. Public means that the MainPage class can be accessed outside of the module (for example, by the Windows Runtime or by another WinRT component). A private type can be accessed only inside the module. Private types give you more freedom to use C++ types in public methods, which isn’t possible with public types. In this case, the MainPage class is public so that it’s accessible to XAML. I’ll look at some examples of private types later.
The ref class keywords tell the compiler that this is a WinRT type and not a C++ type. A ref class is allocated on the heap and its lifetime is reference-counted. Because ref types are reference-counted, their lifetimes are deterministic. When the last reference to a ref type object is released, its destructor is called and the memory for that object is released. Compare this to .NET, where lifetimes are less deterministic and garbage collection is used to free memory.
When you instantiate a ref type, you typically use the ^ (pronounced “hat”) modifier. The ^ modifier is similar to a C++ pointer (*), but it tells the compiler to insert code to manage the object’s reference count automatically and delete the object when its reference count reaches zero.
To create a plain old data (POD) structure, use a value class or value struct. Value types have a fixed size and consist of fields only. Unlike ref types, they have no properties. Windows::Foundation::DateTime and Windows::Foundation::Rect are two examples of WinRT value types. When you instantiate value types, you don’t use the ^ modifier:
Windows::Foundation::Rect bounds(0, 0, 100, 100);
Also notice that MainPage is declared as sealed. The sealed keyword, which is similar to the C++11 final keyword, prevents further derivation of that type. MainPage is sealed because any public ref type that has a public constructor must also be declared as sealed. This is because the runtime is language-agnostic and not all languages (for example, JavaScript) understand inheritance.
Now direct your attention to the MainPage members. The m_processor member variable (the GameProcessor class is defined in the WinRT component project—I’ll talk about that type later) is private simply because the MainPage class is sealed and there’s no possibility that a derived class can use it (and, in general, data members should be private when possible to enforce encapsulation). The OnNavigatedTo method is protected because the Windows::UI::Xaml::Controls::Page class, from which MainPage derives, declares this method as protected. The constructor and the Processor property must be accessed by XAML, and therefore both are public.
You’re already familiar with public, protected and private access specifiers; their meanings in C++/CX are the same as in C++. To learn about internal and other C++/CX specifiers, see bit.ly/Xqb5Xe. You’ll see an example of internal later on.
A ref class may have only publicly accessible types in its public and protected sections—that is, only primitive types, public ref or public value types. Conversely, a C++ type can contain ref types as member variables, in method signatures and in local function variables. Here’s an example from the Hilo C++ project:
std::vector<Windows::Storage::IStorageItem^> m_createdFiles;
The Hilo team uses std::vector and not Platform::Collections::Vector for this private member variable because we don’t expose the collection outside of the class. Using std::vector helps us use C++ code as much as possible and makes its intention clear.
Moving on to the MainPage constructor:
MainPage::MainPage() : m_processor(ref
new TicTacToeLibrary::GameProcessor())
{
InitializeComponent();
DataContext = m_processor;
}
I use the ref new keywords to instantiate the GameProcessor object. Use ref new instead of new to construct WinRT reference type objects. When you’re creating objects in functions, you can use the C++ auto keyword to reduce the need for specifying the type name or use of ^:
auto processor = ref new TicTacToeLibrary::GameProcessor();
Creating the TicTacToe Library
The library code for the TicTacToe game contains a mixture of C++ and C++/CX. For this app, I pretended that I had some existing C++ code that I’d already written and tested. I incorporated this code directly, adding C++/CX code only to connect the internal implementation to XAML. In other words, I used C++/CX only to bridge the two worlds together. Let’s walk through some of the important parts of the library and highlight any C++/CX features not already discussed.
The GameProcessor class serves as the data context for the UI (think view model if you’re familiar with MVVM). I used two attributes, BindableAttribute and WebHostHiddenAttribute, when declaring this class (like .NET, you can omit the “Attribute” part when you declare attributes):
[Windows::UI::Xaml::Data::Bindable]
[Windows::Foundation::Metadata::WebHostHidden]
public ref class GameProcessor sealed : public Common::BindableBase
The BindableAttribute produces metadata that tells the Windows Runtime that the type supports data binding. This ensures that all the public properties of the type are visible to the XAML components. I derive from BindableBase to implement the functionality required to make binding work. Because BindableBase is intended for use by XAML and not JavaScript, it uses the WebHostHiddenAttribute (bit.ly/ZsAOV3) attribute. Per convention, I also marked the GameProcessor class with this attribute to essentially hide it from JavaScript.
I separated GameProcessor’s properties into public and internal sections. The public properties are exposed to XAML; the internal properties are exposed only to other types and functions in the library. I felt that making this distinction helps make the intent of the code more obvious.
One common property usage pattern is binding collections to XAML:
property Windows::Foundation::Collections::IObservableVector<Cell^>^ Cells
{
Windows::Foundation::Collections::IObservableVector<Cell^>^ get()
{ return m_cells; }
}
This property defines the model data for the cells that appear on the grid. When the value of Cells changes, the XAML is updated automatically. The type of the property is IObservableVector, which is one of several types defined specifically for C++/CX to enable full interoperability with the Windows Runtime. The Windows Runtime defines language-independent collection interfaces, and each language implements those interfaces in its own way. In C++/CX, the Platform::Collections namespace provides types such as Vector and Map that provide concrete implementations for these collections interfaces. Therefore, I can declare the Cells property as IObservableVector but back that property by a Vector object, which is specific to C++/CX:
Platform::Collections::Vector<Cell^>^ m_cells;
So when do you use Platform::String and Platform::Collections collections versus the standard types and collections? For example, should you use std::vector or Platform::Collections::Vector to store your data? As a rule of thumb, I use Platform functionality when I plan to work primarily with the Windows Runtime, and standard types such as std::wstring and std::vector for my internal or computationally intensive code. You can also easily convert between Vector and std::vector when you need to. You can create a Vector from a std::vector or you can use to_vector to create a std::vector from a Vector:
std::vector<int> more_numbers =
Windows::Foundation::Collections::to_vector(result);
There’s a copy cost associated when marshaling between the two vector types, so again, consider which type is appropriate in your code.
Another common task is converting between std::wstring and Platform::String. Here’s how:
// Convert std::wstring to Platform::String.
std::wstring s1(L"Hello");
auto s2 = ref new Platform::String(s1.c_str());
// Convert back from Platform::String to std::wstring.
// String::Data returns a C-style string, so you don’t need
// to create a std::wstring if you don’t need it.
std::wstring s3(s2->Data());
// Here's another way to convert back.
std::wstring s4(begin(s2), end(s2));
There are two interesting points to note in the GameProcessor class implementation (GameProcessor.cpp). First, I use only standard C++ to implement the checkEndOfGame function. This is one place where I wanted to illustrate how to incorporate existing C++ code that I’d already written and tested.
The second point is the use of asynchronous programming. When it’s time to switch turns, I use the PPL task class to process the computer players in the background, as shown in Figure 4.
Figure 4 Using the PPL Task Class to Process Computer Players in the Background
void GameProcessor::SwitchPlayers()
{
// Switch player by toggling pointer.
m_currentPlayer = (m_currentPlayer == m_player1) ? m_player2 : m_player1;
// If the current player is computer-controlled, call the ThinkAsync
// method in the background, and then process the computer's move.
if (m_currentPlayer->Player == TicTacToeLibrary::PlayerType::Computer)
{
m_currentThinkOp =
m_currentPlayer->ThinkAsync(ref new Vector<wchar_t>(m_gameBoard));
m_currentThinkOp->Progress =
ref new AsyncOperationProgressHandler<uint32, double>([this](
IAsyncOperationWithProgress<uint32, double>^ asyncInfo, double value)
{
(void) asyncInfo; // Unused parameter
// Update progress bar.
m_backgroundProgress = value;
OnPropertyChanged("BackgroundProgress");
});
// Create a task that wraps the async operation. After the task
// completes, select the cell that the computer chose.
create_task(m_currentThinkOp).then([this](task<uint32> previousTask)
{
m_currentThinkOp = nullptr;
// I use a task-based continuation here to ensure this continuation
// runs to guarantee the UI is updated. You should consider putting
// a try/catch block around calls to task::get to handle any errors.
uint32 move = previousTask.get();
// Choose the cell.
m_cells->GetAt(move)->Select(nullptr);
// Reset the progress bar.
m_backgroundProgress = 0.0;
OnPropertyChanged("BackgroundProgress");
}, task_continuation_context::use_current());
}
}
If you’re a .NET programmer, think of task and its then method as the C++ version of async and await in C#. Tasks are available from any C++ program, but you’ll use them throughout your C++/CX code to keep your Windows Store app fast and fluid. To learn more about async programming in Windows Store apps, read Artur Laksberg’s February 2012 article, “Asynchronous Programming in C++ Using PPL” (msdn.microsoft.com/magazine/hh781020), and the MSDN Library article at msdn.microsoft.com/library/hh750082.
The Cell class models a cell on the game board. Two new things that this class demonstrates are events and weak references.
The grid for the TicTacToe play area consists of Windows::UI::Xaml::Controls::Button controls. A Button control raises a Click event, but you can also respond to user input by defining an ICommand object that defines the contract for commanding. I use the ICommand interface instead of the Click event so that Cell objects can respond directly. In the XAML for the buttons that define the cells, the Command property binds to the Cell::SelectCommand property:
<Button Width="133" Height="133" Command="{Binding SelectCommand}"
Content="{Binding Text}" Foreground="{Binding ForegroundBrush}"
BorderThickness="2" BorderBrush="White" FontSize="72"/>
I used the Hilo DelegateCommand class to implement the ICommand interface. DelegateCommand holds the function to call when the command is issued, and an optional function that determines whether the command can be issued. Here’s how I set up the command for each cell:
m_selectCommand = ref new DelegateCommand(
ref new ExecuteDelegate(this, &Cell::Select), nullptr);
You’ll commonly use predefined events when doing XAML programming, but you can also define your own events. I created an event that’s raised when a Cell object is selected. The GameProcessor class handles this event by checking whether the game is over and switching the current player if needed.
To create an event, you must first create a delegate type. Think of a delegate type as a function pointer or a function object:
delegate void CellSelectedHandler(Cell^ sender);
I then create an event for each Cell object:
event CellSelectedHandler^ CellSelected;
Here’s how the GameProcessor class subscribes to the event for each cell:
for (auto cell : m_cells)
{
cell->CellSelected += ref new CellSelectedHandler(
this, &GameProcessor::CellSelected);
}
A delegate that’s constructed from a ^ and a pointer-to-member function (PMF) holds only a weak reference to the ^ object, so this construct won’t cause circular references.
Here’s how Cell objects raise the event when they’re selected:
void Cell::Select(Platform::Object^ parameter)
{
(void)parameter;
auto gameProcessor =
m_gameProcessor.Resolve<GameProcessor>();
if (m_mark == L'\0' && gameProcessor != nullptr &&
!gameProcessor->IsThinking &&
!gameProcessor->CanCreateNewGame)
{
m_mark = gameProcessor->CurrentPlayer->Symbol;
OnPropertyChanged("Text");
CellSelected(this);
}
}
What’s the purpose of the Resolve call in the preceding code? Well, the GameProcessor class holds a collection of Cell objects, but I want each Cell object to be able to access its parent GameProcessor. If Cell held a strong reference to its parent—in other words, a GameProcessor^—I’d create a circular reference. Circular references can cause objects to never be freed because the mutual association causes both objects to always have at least one reference. To avoid this, I create a Platform::WeakReference member variable and set it from the Cell constructor (think very carefully about lifetime management and what objects own what!):
Platform::WeakReference m_gameProcessor;
When I call WeakReference::Resolve, nullptr is returned if the object no longer exists. Because GameProcessor owns Cell objects, I expect the GameProcessor object to always be valid.
In the case of my TicTacToe game, I can break the circular reference each time a new game board is created, but in general, I try to avoid the need to break circular references because it can make code less maintainable. Therefore, when I have a parent-child relationship and children need to access their parent, I use weak references.
Working with Interfaces
To distinguish between human and computer players, I created an IPlayer interface with concrete implementations HumanPlayer and ComputerPlayer. The GameProcessor class holds two IPlayer objects—one for each player—and an additional reference to the current player:
IPlayer^ m_player1;
IPlayer^ m_player2;
IPlayer^ m_currentPlayer;
Figure 5 shows the IPlayer interface.
Figure 5 The IPlayer Interface
private interface class IPlayer
{
property PlayerType Player
{
PlayerType get();
}
property wchar_t Symbol
{
wchar_t get();
}
virtual Windows::Foundation::IAsyncOperationWithProgress<uint32, double>^
ThinkAsync(Windows::Foundation::Collections::IVector<wchar_t>^ gameBoard);
};
Because the IPlayer interface is private, why didn’t I just use C++ classes? To be honest, I did it to show how to create an interface and how to create a private type that isn’t published to metadata. If I were creating a reusable library, I might declare IPlayer as a public interface so other apps could use it. Otherwise, I might choose to stick with C++ and not use a C++/CX interface.
The ComputerPlayer class implements ThinkAsync by performing the minimax algorithm in the background (see the file ComputerPlayer.cpp in the accompanying code download to explore this implementation).
Minimax is a common algorithm when creating artificial intelligence components for games such as tic-tac-toe. You can learn more about minimax in the book, “Artificial Intelligence: A Modern Approach” (Prentice Hall, 2010), by Stuart Russell and Peter Norvig.
I adapted Russell and Norvig’s minimax algorithm to run in parallel by using the PPL (see minimax.h in the code download). This was a great opportunity to use pure C++11 to write the processor-intensive part of my app. I’ve yet to beat the computer and have never seen the computer beat itself in a computer-versus-computer game. I admit this doesn’t make for the most exciting game, so here’s your call to action: Add additional logic to make the game winnable. A basic way to do this would be to have the computer make random selections at random times. A more sophisticated way would be to have the computer purposely choose a less-optimal move at random times. For bonus points, add a slider control to the UI that adjusts the game’s difficulty (the less difficult, the more the computer either chooses a less-optimal move or at least a random one).
For the HumanPlayer class, ThinkAsync has nothing to do, so I throw Platform::NotImplementedException. This requires that I test the IPlayer::Player property first, but it saves me a task:
IAsyncOperationWithProgress<uint32, double>^
HumanPlayer::ThinkAsync(IVector<wchar_t>^ gameBoard)
{
(void) gameBoard;
throw ref new NotImplementedException();
}
The WRL
There’s a great sledgehammer available in your toolbox for when C++/CX doesn’t do what you need or when you prefer to work directly with COM: the WRL. For example, when you create a media extension for Microsoft Media Foundation, you must create a component that implements both COM and WinRT interfaces. Because C++/CX ref classes can only implement WinRT interfaces, to create a media extension you must use the WRL because it supports the implementation of both COM and WinRT interfaces. To learn more about WRL programming, see bit.ly/YE8Dxu.
Going Deeper
At first I had misgivings about C++/CX extensions, but they soon became second nature, and I like them because they enable me to write Windows Store apps quickly and use modern C++ idioms. If you’re a C++ developer, I highly recommend you at least give them a shot.
I reviewed just some of the common patterns you’ll encounter when writing C++/CX code. Hilo, a photo app using C++ and XAML, goes deeper and is much more complete. I had a great time working on the Hilo C++ project, and I actually refer back to it often as I write new apps. I recommend that you check it out at bit.ly/15xZ5JL.
Thomas Petchel works as a senior programming writer in the Microsoft Developer Division. He has spent the past eight years with the Visual Studio team creating documentation and code samples for the developer audience.
Thanks to the following technical experts for reviewing this article: Michael Blome (Microsoft) and James McNellis (Microsoft)
Michael Blome has worked for more than 10 years at Microsoft, engaged in the Sisyphean task of writing and rewriting MSDN documentation for Visual C++, DirectShow, C# language reference, LINQ and parallel programming in the .NET Framework.
James McNellis is a C++ aficionado and a software developer on the Visual C++ team at Microsoft, where he builds awesome C and C++ libraries. He is a prolific contributor on Stack Overflow, tweets at @JamesMcNellis.