Here are some tips and coding guidelines for creating
Windows Store apps using C++ and XAML, including how to adapt to asynchronous programming using the Parallel Patterns Library (PPL). They arose from questions
we ourselves asked as we started developing Hilo C++.

Applies to

Windows Runtime for Windows 8

C++/CX

Understanding the app's environment

Windows Store apps, such as Hilo, include a distinctive visual design and
often feature touch-based interaction. In
addition, they run in an
environment that gives the user more control over what the app
is allowed to do compared to desktop and console apps. The extra control helps make the app secure and easier for the user to manage.

These features have implications for the way you implement
the app. If you’re using C++, here’s what establishes your
app’s static and run-time environment.

These components and tools determine what platform capabilities are available to your app and how you
access these capabilities. If you're new to Windows Store apps, review the overviews of these
components and tools to learn how they contribute to your app. You'll see how
each component and tool is used in Hilo as you read through this
guide.

The package manifest

Visual Studio creates a
project file named Package.appxmanifest to record
settings that affect how the app is deployed and how it runs. The file is known as the package
manifest. Visual Studio lets you edit the package manifest using a visual tool that
is called the Manifest
Designer.

Unlike desktop and console apps, Windows Store apps must declare in advance the environment capabilities that they intend to use, such as accessing
protected system resources or user data.

You must declare all capabilities in the package
manifest before your app can use them. You can use the Capabilities tab in the Manifest Designer to do this. For example, the
Hilo manifest includes the ability to access the user’s
picture library.

Windows Store apps run within a special
operating system environment. This environment allows
the app to only use features of the Windows Runtime that the
package manifest has declared as requested
capabilities. To achieve this, the system restricts the
functions, data types, and devices that the app can
use.

Note The package manifest only restricts calls to the
Windows Runtime API. If you use Win32
or the COM API, you'll need to run tools that make sure you're using
the API subset that is allowed for apps on the Windows
Store. Visual Studio helps you adhere to the correct API
subset by filtering functions in the Object
Browser.

C++ standard libraries

The Visual C++ compiler supports the C++11
standard that lets you use a modern coding style. Your
Windows Store app can use the C run-time library (CRT) and
the Standard Template Library (STL). There are a few
restrictions, such as no access to console I/O. (See
Porting
existing C++ code on this
page.)

Windows Runtime libraries

The Windows Runtime is a programming interface that
you can use to create Windows Store apps. Windows Runtime supports the distinctive visual style and
touch-based interaction model of Windows Store apps as well as access to network, disks, devices,
and printing. The data types and functions in these
libraries use the Windows and Platform
namespaces. The Object
Browser in Visual Studio lets you examine what types are
available.

At the lowest level, the Windows Runtime consists of an application binary interface (ABI). The ABI
is a binary contract that makes Windows Runtime APIs
accessible to multiple programming languages such as JavaScript, the .NET
languages, and Microsoft Visual C++. For more info
about the Windows Runtime API, see Windows API reference for Windows Store apps.

The structure of a Windows Store app differs from that
of a traditional desktop app using the Windows API
(Win32). Instead of working with handle types such as
HWND and functions such as
CreateWindow, the Windows Runtime provides interfaces such as Windows::UI::Core::ICoreWindow
so that you can develop Windows Store apps in a
more modern, object-oriented way.

Note Part of the richness of the Windows Runtime programming model comes from an extended type system and additional language capabilities. The environment provides properties, delegates, events, interfaces and attributes. See Type system (C++/CX) for an overview.

Win32 and COM API

Windows Store apps can use a subset of the
Win32 and COM
API. Although the Windows Runtime provides a rich set
of functionality, you can continue to use a subset of Win32 and COM to support key
scenarios for Windows Store apps that aren't
already covered by the Windows Runtime. For example,
IXMLHTTPRequest2, a
COM interface, is the recommended way to
connect to HTTP servers in a Windows Store app using
C++. See Win32 and COM API
for more info about using Win32 and COM in your Windows Store app. See Porting
existing C++ code on this page
for an overview of what's included.

Hilo doesn't
call the Win32 API directly. However, it does use COM
to work with image pixel data.

XAML

Windows Store apps using Extensible
Application Markup Language, or XAML, use a declarative
approach for defining the visual presentation of the
app. The design and structure of the UX are encoded in
XAML, an XML-based markup language. You can use a visual
design tool, such as the Visual Studio designer or Microsoft Expression Blend, to define UI
elements, or you can write XAML expressions yourself, or
both. You use XAML data binding expressions to connect UI
elements to data sources in your app.

XAML is the design language for frameworks such as Microsoft Silverlight and Windows Presentation Foundation (WPF). If you're
familiar with using XAML with these frameworks or with
Expression Blend, you'll be able to continue using
your skills when you create Windows Store apps. For more info about XAML as it relates to Windows Store apps, see XAML
overview.

Data binding is a convenient
way for text boxes, buttons, data grids, and other UI
elements to connect to app logic. The Windows Runtime
invokes methods and properties of the data sources as
needed to supply the UI with information as the app
runs. Data binding is also used in cases where the data
being passed is a command, such as a request to perform an
operation like opening a file. In this case, data binding decouples UI elements that invoke commands from the code that executes the command action. Nearly every object and
property of the framework can be bound in XAML.

Visual Studio project templates

We recommend that you use the built-in Visual Studio project templates because they define the compiler settings needed to run a Windows Store app. The project templates also provide code that implements basic functionality, saving you time. Visual Studio puts some files in a solution folder named
Common, which you shouldn’t modify. Visual Studio also creates an
App.xaml.cpp file that you can customize with app-specific
logic. This file includes the main entry point to the app,
the App::InitializeComponent method. Although the Visual Studio
templates save time, they aren’t required. You can also modify existing static and dynamic libraries for use in your app. For more info, see Porting
existing C++ code on this
page and Building apps and libraries (C++/CX).

C++ language extensions for interop

The new user interface framework for Windows Store apps uses XAML to interact with native C++. The
interop between C++ and XAML, or other languages such as
JavaScript and C#, is direct, without calls to an
intermediary translation layer. Interop uses a convention
for the binary format of objects and function calls that
is similar to COM-based programming. The programming
environment for Windows Store apps includes
C++/CX, which provides C++ language extensions that make
interop easy to code. The extensions are only intended to
be used with code that deals with interop. The rest of
your app should use standards-compliant C++. For more info see
Tips
for using C++/CX as an interop layer on this
page.

Note You don't have to use the C++/CX for interop. You can also achieve interop with WRL.

The C++ compiler and linker

The /ZW compiler option enables C++ source files to use
features of the Windows Runtime. It also enables the
__cplusplus_winrt preprocessor directive that you'll see
in some system header files. Your code gets declarations
of Windows Runtime types from metadata (.winmd) files instead of from header files. You
reference .winmd files with the #using directive, or the
/FU compiler option. Visual Studio configures these
options for you if you use one of the C++ project
templates for Windows Store apps.

When you link the app, you need to provide two linker options:
/WINMD and /APPCONTAINER. Visual Studio configures these
options for you if you use one of the C++ project
templates for Windows Store apps.

Certification process of the Windows Store

Publishing to the Windows Store makes your app
available for purchase or free download. Publishing to the
store is optional. Apps in the store must undergo a
certification process that includes an automated
structural check. For a description of Hilo's
certification experience, see Testing and deploying the app in this
guide.

Deployment

Windows Store apps use a simpler installation model than
desktop apps. In a Windows Store app, all libraries and
resources, other than those provided by the system, are located
in the app’s installation directory or subdirectories. The installation process
for a Windows Store app cannot write to the system registry
or define environment variables. In addition, the user can
limit the capabilities of the app they're
installing. The package manifest lists all the files that are deployed. For more information, see The package manifest.

Using C++11, standard C++ libraries, and a modern coding style

When possible, use C++11 and the standard C++ libraries (for example, the STL and CRT) for your core app logic and the C++/CX syntax only at the boundary where you interact with the Windows Runtime. For example, it's best if you use these techniques:

Lambda expressions

Stack semantics, smart pointers, and RAII

Use stack semantics, smart pointers, and Resource Acquisition is Initialization (RAII) to automatically control object lifetime and ensure that resources are freed when the current function returns or throws an exception. For more info, see Tips for managing memory on this page.

Automatic type deduction

Use automatic type deduction to make code easier to read and faster to write. The auto and decltype keywords direct the compiler to deduce the type of a declared variable from the type of the specified expression. For example, you can use auto when you work with STL iterators, whose names can be tedious to type and don't add clarity to your code. Hilo makes extensive use of auto when it uses the concurrency::create_task and std::make_shared functions to reduce the need to declare the template type parameter.

Note Use the auto keyword when readers of your code can understand the type from the context, or when you want to abstract the type. The motivation is readability.

Range-based for loops

Use range-based for loops to work with collections of data. Range-based for loops have a more succinct syntax than for loops and the std::for_each algorithm because they don't require you to use iterators or capture clauses. Here's an example:

By using standard functionality, you can write code that's more portable and takes advantage of modern C++ features such as move semantics. (For more info about move semantics, see Rvalue Reference Declarator: &&.)

The same pattern applies to standard containers, such as std::vector. Using standard containers enables you to take advantage of C++ features such as move semantics and the ability to work with memory more directly. For example, you might perform internal processing on a std::vector object and then need to pass a Windows::Foundation::Collections::IVector object to the Windows Runtime. The Platform::Collections::Vector class, which is the C++ implementation of IVector, has an overloaded constructor that takes an rvalue reference to a std::vector. To call the overloaded constructor, use the std::move function or directly pass the result of a function that returns std::vector. For an example that shows this pattern, see Collections (C++/CX).

Note You don't have to use move semantics. The Platform::Collections::Vector class includes a standard copy constructor that takes a std::vector object as its argument. In other words, you can keep your old vector data and create a new Platform::Collections::Vector instance with a copy of the original data.

As another example, Hilo uses std::iota and std::random_shuffle to choose random photos (more precisely, indices to an array of photos). This example uses std::iota to create a sequence of array indices and std::random_shuffle to randomly rearrange the sequence.

Free-form iterators

Use the std::begin and std::end functions to work with ranges. Use these functions, instead of member functions such as .begin() and .end(), to write more flexible code. For example, you can write a generic algorithm that works with both STL types such as std::vector, std::array, and std::list, which provide begin and ends member functions, and also Windows Runtime collection types such as IVector, which use a different technique to iterate over values. The std::begin and std::end functions can be overloaded to accommodate different programming styles and also enable you to add iteration to data structures that you cannot alter.

The pimpl idiom

Use the pimpl idiom to hide implementation, minimize coupling, and separate interfaces. Pimpl (short for "pointer to implementation") involves adding implementation details to a .cpp file and a smart pointer to that implementation in the private section of the class declaration in the .h file. Doing so can also shorten compile times. Pimpl, when used together with copy construction and move semantics, also enables you to pass objects by value, which helps eliminate the need to worry about object lifetimes.

You can also take advantage of the pimpl idiom when you use predefined libraries. Pimpl is often related to rvalue references. For example, when you create task-based continuations, you pass concurrency::task objects by value and not by reference.

Passing by value guarantees that the object is valid and eliminates the need to worry about object lifetime. Additionally, passing by value isn't expensive in this case because the task class defines a pointer to the actual implementation as its only data member and copies or transfers that pointer in the copy and move constructors.

Exception handling

Use exception handling to deal with errors. Exception handling has two main advantages over logging or error codes (such as HRESULT values):

It can make code easier to read and maintain.

It's a more efficient way to propagate an error to a function that can handle that error. The use of error codes typically requires each function to explicitly propagate errors.

It can make your app more robust because you can't ignore an exception as you might an HRESULT or GetLastError status.

You can also configure the Visual Studio debugger to break when an exception occurs so that you can stop immediately at the location and context of the error. The Windows Runtime also uses exception handling extensively. Therefore, by using exception handling in your code, you can combine all error handling into one model.

Important Catch only the exceptions that you can safely handle and recover from. Otherwise, don't catch the exception and allow the app to terminate. Don't use catch(...) {...} unless you rethrow the exception from the catch block.

Here's an example from Hilo that shows the modern C++ coding style C++11 and standard libraries that copy StorageFile objects from a std::vector object to a Vector object so that the collection can be passed to the Windows Runtime. This example uses a lambda expression, automatic type deduction, std::begin and std::end iterators, and a range-based for loop.

Adapting to async programming

With async programming you call a function that starts a long-running operation but returns immediately without waiting for the work to be finished. Async operations help improve the responsiveness of the user experience. You'll find many more asynchronous operations in the Windows Runtime than in earlier frameworks.

You can tell if a Windows Runtime function is asynchronous from its name. The names of asynchronous functions end in "Async" such as ReadTextAsync. Hilo also follows this naming convention.

Each programming language provides native support for asynchronous programming and uses IAsyncInfo-derived interfaces for interop. In the case of C++, PPL provides the native support for async programming. In general, you should wrap the Windows Runtime's async interface types using PPL tasks when you get them from a call to a Windows Runtime async method. The only time you should expose these interfaces from your own classes is to create a Windows Runtime component for cross-language interop. For example, you use IAsyncInfo-derived types in public methods and properties of publicref classes that you define.

After wrapping an async operation with a PPL task, you can create additional tasks that the system schedules for execution after the prior task completes. The successor tasks are called continuation tasks (or continuations). You create continuations with the task::then method. Here's an example from Hilo that uses async operations to read an image from a file.

Note The declarations of PPL tasks are located in the ppltasks.h header file.

The expression m_photo->File returns a Windows::Storage::StorageFile^ reference. This object's OpenReadAsync method starts an asynchronous operation function to open the file that contains the requested image. The call to OpenReadAsync returns an object of type IAsyncOperation<IRandomAccessStreamWithContentType^>^.

The async invocation starts the operation. The call itself returns very quickly, without waiting for the file open operation to complete. The return value of the call to OpenReadAsync represents the running operation that was started. The return type is parameterized by the asynchronous operation’s result type, which in this case is IRandomAccessStreamWithContentType^.

The Photo::QueryPhotoImageAsync method then calls the concurrency::create_task function to produce a new PPL task that becomes the value of the local variable imageStreamTask. The type of the imageStreamTask variable is task<IRandomAccessStreamWithContentType^>. The effect of passing a Windows Runtime asynchronous object to the concurrency::create_task function is to wrap the asynchronous operation with a PPL task. The newly created PPL task finishes when the OpenReadAsync operation completes its work and a random access stream is available.

Async operations of the Windows Runtime do not always require their own threads to run. Windows often manages them as overlapped I/O operations using internal data structures that have less overhead than threads. This detail is internal to the operating system.

After a Windows Runtime operation is wrapped with a PPL task, you can use the task::then method to create continuations that run after the previous, or antecedent, task completes. Continuations are themselves PPL tasks. They make asynchronous programs easier to read and debug.

The task::then method is asynchronous. It returns a new task very quickly. Unlike other async tasks, the task returned by the task::then method doesn't begin to run immediately. Instead, PPL delays the start of the task's execution until the result of the antecedent task becomes available. This means that although the task::get method is synchronous when applied to the antecedent task, the value is immediately available. Continuation tasks that aren't ready to run don't block any threads. Instead, they are managed by the PPL internally until the data they need becomes available.

In the QueryPhotoImageAsync method shown above, the argument to the then method is a lambda expression that's the work function of the newly created task. (A task’s work function is the code that gets invoked when the task runs.) The type of the lambda expression’s input parameter matches the type of the imageStreamTask. The types match because the imageStreamTask is passed as an argument to the continuation’s work function when the continuation begins to run. You can think of this as a kind of data flow programming. Continuation tasks begin to run when their inputs become available. When they finish running, they pass their results to the next continuation task in the chain.

In Windows Store apps, continuations of tasks that wrap IAsyncInfo objects run by default in the thread context that created the continuation. In most cases, the default context will be the app’s main thread. This is appropriate for querying or modifying XAML controls, and you can override the default to handle other cases.

Note In Hilo, we found it useful to clarify our understanding of the thread context for our subroutines by using assert(IsMainThread() and assert(IsBackgroundThread()) statements. In the Debug version of Hilo, these statements break into the debugger if the thread being used is other than the one declared in the assertion. The IsMainThread and IsBackgroundThread functions are in the Hilo source.

This example didn’t need any special synchronization code, such as a lock or a critical section, for the update to the m_image member variable. This is because all interactions with view model objects occur on the main thread. Using a single thread automatically serializes any potentially conflicting updates. In UI programming, it’s a good idea to use continuations that run in a known thread context instead of other kinds of synchronization.

Using parallel programming and background tasks

The goal of asynchronous programming is interactive responsiveness. For example, in Hilo we use asynchronous techniques to make sure that the app’s main thread remains unblocked and ready to respond to new requests without delay. However, depending on your app’s functional requirements, you might need to ensure the responsiveness of the user experience and the overall throughput of the compute-intensive parts of your app.

C++ is particularly well-suited for apps that need to have both a responsive user interface and high performance for compute-intensive tasks. The concurrency features of Visual C++ can meet the needs of both sets of requirements.

You can increase the throughput of the compute-intensive areas of your app by breaking some tasks into smaller pieces that are performed concurrently by multiple cores of your CPU or by the specialized data-parallel hardware of your computer’s graphics processor unit (GPU). These techniques and others are the focus of parallel programming. We use parallel programming techniques in several areas of Hilo.

For example, one of Hilo's features is a cartoon effect that you can use to stylize an image using simpler colors and shape outlines. Here's what an image looks like before and after applying this effect.

The cartoon effect is computationally intensive. Hilo's implementation uses C++ AMP to calculate the result quickly on the GPU. On systems that don't have a compute-class GPU available, Hilo uses the PPL, which is part of the Concurrency Runtime. Here's how we use the accelerator::is_emulated property to determine whether to use the C++ AMP or the PPL algorithm to perform the cartoon effect:

Tip We chose to run the algorithm that uses the PPL when the required hardware is not available because we already had the code available that leverages all CPU cores. However, if you do not have fallback code available, you can still use the WARP or reference device to run your C++ AMP code. Profile your C++ AMP code on multiple configurations to help you determine if you need to consider a similar fallback method.

See the CartoonEffect project in the Hilo source files for details on how we implemented these algorithms.

When you apply parallel programming techniques you need to think in terms of foreground processing (on the main thread) and background processing (on worker threads). PPL tasks help you control which parts of the app run in the main thread and which parts run in the background. Operations that read or modify XAML controls are always invoked on the app’s main thread. However, for compute-intensive or I/O-intensive operations that don’t modify the user interface, you can take advantage of the computer’s parallel processing hardware by using PPL tasks that run on threads from the system’s thread pool.
You can see the foreground/background pattern in the Crop action. Here's the code:

The code shows Hilo's image cropping operation. The UI for the crop operation shows crop handles for the user to manipulate. After specifying the crop region, the user taps the image to generate a preview of the cropped image. The cropping operation's Grid control fires a Tapped event whose code-behind handler invokes the CropImageAsync method in the example.

Because an event handler invokes it, the CropImageAsync method runs on the main thread. Internally, it divides its work between the main thread and a background thread in the thread pool. To do this, it uses the concurrency::create_task function to schedule the DoCrop method in a background thread.

Note While the DoCrop method is running in the background, the main thread is free to do other work in parallel. For example, while the DoCrop method runs, the main thread continues to animate the progress ring and respond to navigation requests from the user.

After the DoCrop method completes, a continuation task begins to run on the main thread to update the XAML controls.

Here's a diagram of the crop operation's use of threads.

The DoCrop method runs in a background thread, but it also uses PPL's parallel_for function to perform a compute-intensive operation using the computer's multicore hardware. Here's the code.

The code is an example of how you can integrate parallel programming techniques into your app. Parallelizing only the outer loop maximizes the benefits of concurrency. If you parallelize the inner loop, you will not receive a gain in performance because the small amount of work that the inner loop performs does not overcome the overhead for parallel processing.

For a modern programming style and best performance, we recommend that you use PPL's parallel algorithms and data types for new code.

Tips for using C++/CX as an interop layer

Here are some tips for cross-language interop that we
developed during the creation of Hilo. (For complete
documentation of the language extensions that are available to
a C++ Windows Store app for cross-language interop, see Visual C++ language reference (C++/CX).)

Be aware of overhead for type conversion

In order to interact with Windows Runtime features,
you sometimes need to create data types from the Platform and Windows namespaces. You should create these types in the most efficient way.

For example, if you create a Windows::Foundation::Collections::Vector^
reference from a std::vector object, the Vector constructor may perform a
copy. If you allocate a std::vector object and know that
there are no other references to it, you can create a Vector object without copying by
calling the std::move function on the
std::vector before passing it
to the Vector constructor. This
works because the Vector class
provides a move constructor that takes a std::vector<T>&&
argument.

Call methods of ref classes from the required thread

Some ref classes require their methods, events and properties to be accessed from a specific thread. For example, you must interact with XAML classes from the main thread. If you create a new class that derives from an existing Windows Runtime class, you inherit the context requirements of the base class.

Be careful to respect the threading model of the objects you use.

Reference counts can be decremented as a side effect of operations that occur in any thread. For this reason, you should make sure that destructors for ref classes that you implement can be called from any thread. You must not invoke methods or properties in your destructor that require a specific thread context.

For example, some Windows Runtime classes require you to unregister event handlers in the main thread. Here is a code example of a thread-safe destructor that does this.

The run_async_non_interactive function is a utility function that is defined in Hilo. It dispatches a function object to the main thread, allowing UI interactions by the user to have higher priority.

Mark destructors of public ref classes as virtual

Destructors of public ref classes must be declared virtual.

Use ref classes only for interop

You only have to use ^ and
ref new when you create Windows Runtime objects or create Windows Runtime
components. You can use the standard C++ syntax when you
write core application code that doesn't use the Windows Runtime.

Hilo uses ^ and std::shared_ptr
to manage heap-allocated objects and minimize memory
leaks. We recommend that you use ^ to manage the lifetime of Windows Runtime variables, ComPtr to manage the lifetime of
COM variables (such as when you use DirectX), and std::shared_ptr
or std::unique_ptr
to manage the lifetime of all other heap-allocated C++
objects.

We recommend that you declare all ref classes as public
because they're only intended for interop. If you have
private, protected, or internalref classes, it's an
indication that you're attempting to use ref classes for
implementation purposes and not interop across the
Abstract Binary Interface (ABI).

Use techniques that minimize marshaling costs

C++/CX is designed for language interop. When you call functions across the ABI, you sometimes incur overhead due to the cost of marshaling (copying) data. Because the XAML UI framework is written in C++, you don't incur marshaling overhead when you interoperate with XAML from a C++ app. If you implement a component in C++ that is called from a language other than C++ or XAML, your app would incur some cost for marshaling.

Use the Object Browser to understand your app's .winmd output

When you build your app, the compiler creates a .winmd
file that contains metadata for all the public ref
types that your app defines. Components such as XAML use
the .winmd file to invoke methods of your app's data types
across the ABI.

It's often helpful to examine what's in the generated
.winmd file. To see this, you can use the Visual Studio
Object Browser. From the Object Browser, navigate
to the .winmd file in your project's Debug directory and
open it. You'll be able to see all the types that
your app exposes to XAML.

Note Be aware of what public ref types you're
including in your app's .winmd file.

If C++/CX doesn't meet your needs, consider WRL for low-level interop

The language extensions of C++/CX save time, but you
don’t have to use them. You can get lower-level access to
cross-language interop from standard C++ if you use the
Windows Runtime C++ Template Library (WRL). WRL uses
conventions that will be familiar to COM programmers.

WRL is a compiler-agnostic way to create and consume
Windows Runtime APIs. You can use the WRL instead of the
C++/CX syntax. It enables you to optimize your code for
performance or for specific scenarios. It also supports
app development methodologies that don't use
exceptions. For more info, see Windows Runtime C++ Template
Library.

In Hilo, we found that C++/CX had the features and
performance we needed. We only used the WRL to access a COM interface that enabled us to read pixel data from an image. In general, WRL is a good candidate when you have a COM object that you want to port to be a Windows Runtime object, since WRL roots are in ATL.

Don't confuse C++/CX language extensions with C++/CLI

The syntax of C++/CX language extensions and C++/CLI
are similar, but there are two very different execution
models. Here's how to think about this.

In order to call Windows Runtime APIs from
JavaScript and .NET, those languages require projections that are specific to each
language environment. When you call a Windows Runtime
API from JavaScript or .NET, you're invoking the projection, which in
turn calls the underlying ABI function. Although you can
call the ABI functions directly from standard C++,
Microsoft provides projections for C++ as well, because
they make it much simpler to consume the Windows Runtime APIs, while still maintaining high
performance.

Microsoft also provides language extensions to Visual
C++ that specifically support the Windows Runtime
projections. Many of these language extensions resemble
the syntax for the C++/CLI language. However, instead of
targeting the common language runtime (CLR), C++ apps use
this syntax to generate native code that's compatible
with the binary format requirements of the ABI.

Because there's no runtime to manage memory, the
system deletes C++/CX objects based on reference counting,
in a manner that's similar to std::shared_ptr. The handle-to-object
operator, or hat (^), is an important part of
the new syntax because it enables reference
counting. Instead of directly calling methods such as AddRef and Release to manage the lifetime of a
Windows Runtime object, the runtime does this for you. It deletes the object
when no other component references it, for example, when it
leaves scope or you set all references to nullptr.

Another important part of using Visual C++ to create Windows Store apps is the ref new
keyword. Use ref new instead
of new to create
reference-counted Windows Runtime objects. For more
info, see Type System (C++/CX).

Don't try to expose internal types in public ref classes

Public ref classes produce metadata that is exposed in
the app's .winmd file. The metadata describes each of the
types and the members of each type. In order for the
metadata to be complete, every member of a public type
must itself be a publicly visible type. As a result,
there's a requirement that you can't expose internal types
as public members of a public ref class.

The requirement of metadata can affect the design of
your app. In general, try to partition your
types so that your public ref types are used exclusively
for interop and not for other purposes in your app. If you're not careful, it's possible that you'll see an
unintended proliferation of public ref classes in your
app.

Tips for managing memory

Because you don't typically close Windows Store apps and because Windows Store apps run on tablets of varying hardware capabilities, it's important to be aware of the amount of memory your app uses. It's especially important to prevent memory leaks by not allowing objects to remain in memory that are not accessible by code. Also consider the lifetime of every object to ensure you don't keep it in memory longer than it needs to be. For efficient memory management, we recommend that you:

Use smart pointers

Use smart pointers to help ensure that programs are free of memory and resource leaks and are exception-safe. In Windows Store apps, use handle-to-object, ^ (pronounced "hat"), to manage the lifetime of Windows Runtime variables, Microsoft::WRL::ComPtr to manage the lifetime of COM variables, (such as when you use DirectX), and std::shared_ptr
or std::unique_ptr
to manage the lifetime of all other heap-allocated C++
objects.

It's easy to remember to use ^ because when you call ref new, the compiler generates code to allocate a Windows Runtime object and then returns a handle to that object. Windows Runtime methods that don't return value types also return handles. What's important to focus on is the use of standard pointer types and COM objects to eliminate memory and resource leaks.

In Hilo, we needed to directly access pixel data to crop images and to apply the cartoon effect to images. To do so, we needed to convert an IBuffer object to its underlying COM interface, IBufferByteAccess. We cast the IBuffer object to the underlying IInspectable interface and called QueryInterface to retrieve a pointer to a supported interface on the object. We also used the ComPtr class to manage the pointers so that calls to AddRef and Release were not necessary.

// Retrieves the raw pixel data from the provided IBuffer object.// Warning, the lifetime of the returned buffer is controlled by the lifetime of the// buffer object passed to this method, once the buffer has been released // pointer will be invalid and must not be used.
byte* GetPointerToPixelData(IBuffer^ buffer, unsignedint *length)
{
if (length != nullptr)
{
*length = buffer->Length;
}
// Query the IBufferByteAccess interface.
ComPtr<IBufferByteAccess> bufferByteAccess;
ThrowIfFailed(reinterpret_cast<IInspectable*>(buffer)->QueryInterface(IID_PPV_ARGS(&bufferByteAccess)));
// Retrieve the buffer data.
byte* pixels = nullptr;
ThrowIfFailed(bufferByteAccess->Buffer(&pixels));
return pixels;
}

Because we're working with COM, we defined the ThrowIfFailed function to more easily deal with HRESULT values. You can use this utility function in your code when you need to convert a failure code to a Windows Runtime exception.

Use stack semantics and the RAII pattern

Stack semantics and the RAII pattern are closely related.

Use stack semantics to automatically control object lifetime and help minimize unnecessary heap allocations. Also use stack semantics to define member variables in your classes and other data structures to automatically free resources when the parent object is freed.

Use the resource acquisition is initialization (RAII) pattern to ensure that resources are freed when the current function returns or throws an exception. Under the RAII pattern, a data structure is allocated on the stack. That data structure initializes or acquires a resource when it's created and destroys or releases that resource when the data structure is destroyed. The RAII pattern guarantees that the destructor is called before the enclosing scope exits. This pattern is useful when a function contains multiple return statements. This pattern also helps you write exception-safe code. When a throw statement causes the stack to unwind, the destructor for the RAII object is called; therefore, the resource is always correctly deleted or released. Using the std::shared_ptr template class for stack-allocated variables is an example of the RAII pattern.

Don't keep objects around longer than you need

Use stack semantics or set references to nullptr to help ensure that objects are freed when they have no more references.

In Hilo, we preferred the use of stack semantics over member variables for two reasons. First, stack semantics helps ensure that memory is only used in the context of where it's needed. Because Hilo is a photo app, we found it particularly important to free image data as soon as possible to keep memory consumption to a minimum. The same applies to other kinds of apps. For example, in a blog reader, you might want to release network connections when they're no longer needed to allow other apps to use those resources.

Second, because much of the app depends on asynchronous actions, we wanted to restrict variable access to the code that needs it to help make the app concurrency-safe. In traditional multithreading programming that doesn't use lambda expressions, you often need to store state as member variables. Here's an example where we used local variables and capture semantics instead of member variables to asynchronously create a thumbnail from an image on disk.

If your app requires the use of a member variable, you should set that variable to nullptr when you no longer need it.

Avoid circular references

Objects involved in a circular reference can never reach a reference count of zero and are never destroyed. Avoid circular references in your code by replacing one of the references with a weak reference.

For example, Hilo defines the IPhoto and IPhotoGroup interfaces. IPhoto encapsulates info about a photo (its file path, image type, date taken, and so on). IPhotoGroup manages collections of photos (for example, all the photos in a given month). These interfaces have a parent-child relationship— you can get an individual photo from a photo group or the parent photo group from a photo. If we were to use standard, or strong, references, a photo and its group will always hold one reference to the other, and the memory for neither is ever freed, even after all other references are released.

Instead, Hilo uses weak references to avoid circular references like this. A weak reference enables one object to reference another without affecting its reference count.

The Windows Runtime provides the WeakReference class. Its Resolve method returns the object if it is valid; otherwise it returns nullptr. Here is how the Photo class, which derives from IPhoto, declares a weak reference to its parent group:

Hilo also uses std::weak_ptr to break circular references. Use WeakReference when you must expose a weak reference across the ABI boundary. Use std::weak_ptr in internal code that doesn't interact with the Windows Runtime.

Capturing an object's this handle in a lambda expression can also cause a circular reference if you use the lambda as an event handler or pass it to a task that the object references.

Note Within member functions of a ref class, the type of the symbol this is a const handle (^), not a pointer.

An object's event handlers are detached from the source when that object is destroyed. However, a lambda expression that captures this increments that object's reference count. If an object creates a lambda expression that captures this and uses that lambda as the handler of an event that is provided by itself or an object it directly or indirectly references, the object's reference count can never reach zero. In this case, the object is never destroyed.

Hilo prevents the circular reference by using member functions instead of lambda expressions to work with events. Here's an example from the HiloPage class.

In this example, NavigateEventHandler is a delegate type defined by Hilo. A delegate is a ref class that's the Windows Runtime equivalent of a function object in standard C++. When you instantiate a delegate using an object handle and a pointer to a member function, the object's reference count is not incremented. If you invoke the delegate instance after the target object has been destroyed, a Platform::DisconnectedException will be raised.

In addition to the two-argument constructor that is shown in this example, delegate types also have an overloaded constructor that accepts a single argument. The argument is a function object such as a lambda expression. If this example captured the object's this handle in a lambda expression and passed the lambda as the delegate's constructor argument, then the object's reference count would be incremented. The reference count would be decremented only when there were no more references to the lambda expression.

If you use lambdas as event handlers, you have two ways to manage memory. You can capture weak references instead of object handles. Or, you can be careful to unsubscribe from events at the right time and break circular references before they cause problems with memory management.

In Hilo, we chose member functions for event callbacks because we felt that this was the easiest to code correctly.

Use breakpoints and tracepoints

A breakpoint tells the debugger that an application should break, or pause, execution at a certain point. A tracepoint is a breakpoint with a custom action associated with it. For Hilo, we used breakpoints extensively to examine app state when running PPL continuation tasks.

You can configure breakpoints to trigger when certain conditions are true. For Hilo, we had an interaction between XAML and the C++ code-behind that we needed to debug. However, the issue occurred only after the code had run at least 20 times. So we used the Hit Count setting to break after the breakpoint was hit at least 20 times.

For Hilo, we found tracepoints to be especially useful to diagnose from which thread certain PPL tasks were running. The default tracepoint message contained all the info we needed.

Use OutputDebugString for "printf" style debugging

Use OutputDebugString when you don't require breaking into the debugger. OutputDebugString also works with tools such as WinDbg and can be used with Release mode.

Caution You can also use TextBlock and other XAML controls to perform "printf" style debugging. However, we preferred the use of OutputDebugString because using a control can affect the layout of pages in ways you may not expect after you remove them. If you use controls to debug your code, be sure to remove them and then test your code before you deploy your app.

Break when exceptions are thrown

When you break in a catch statement, you don't know what code threw the exception. From Visual Studio, choose Debug, Exceptions, and then choose Thrown to break when the exception is thrown. This technique is especially useful when using PPL tasks because you can examine the specific threading context under which the error occurred.

Important It's important to catch every exception that is thrown by PPL tasks. If you don't observe an exception that was thrown by a PPL task, the runtime terminates the app. If your app terminates unexpectedly, enable this feature to help diagnose where the exception occurred.

Use remote debugging to debug your app on a computer that doesn't have Visual Studio. This is useful when you have a computer with a different hardware configuration than your computer that is running Visual Studio. For more info, see Running Windows Windows Store apps on a remote machine.

Porting existing C++ code

If you have existing code in C++ that you want to port to
your Windows Store app, the amount of work that you need to do
depends on the code. Code that uses previous UI frameworks
needs to be rewritten, while other types of code, such as
business logic and numerical routines, can generally be ported
without difficulty. If you are using code written by someone else, you might also check to see whether a version already exists for Windows Store apps. In Hilo, we adapted existing code that performs the cartoon effect and ported it for use as a static library (see the CartoonEffect project in the Hilo source files.) We did not introduce any Windows Runtime dependencies in the static library, which allows us to target previous versions of Windows and Windows 8 desktop apps.

Windows Store apps using C++ can reference
existing static libraries, DLLs, and COM
components, as long as all the existing code that your app
calls meets the requirements for Windows Store apps. In Windows Store apps, all components,
including static libraries and DLLs, must be local to the app
and packaged in the manifest. All the components in the app’s
package must adhere to the requirements for Windows Store apps.

Overview of the porting process

Here’s an outline of how to port existing C++ to make
it usable in a Windows Store app. We used this process
when porting the existing code that we brought into
Hilo.

Compile and test the code on Windows 8

The first step for porting is to compile and test
your existing code on Windows 8. Code that compiles
and runs on Windows 7 should require very few changes
on Windows 8, but it’s a good idea to identify any
platform dependencies before you port your code for
use in a Windows Store app.

When writing Hilo, we reused the code that
performs the cartoon effect image filtering from an earlier project. This
code compiled and ran without change on the
Windows 8 platform.

Note Because porting can change the original code, it's a good idea to create unit tests for the original code before starting the port. You can use the Microsoft Visual StudioNative Testing framework to do this.

You can also use the compiler preprocessor
directive WINAPI_FAMILY=WINAPI_PARTITION_APP
to help find incompatibilities. This directive causes
the C++ compiler to issue errors when it encounters
calls to unsupported functions.

Tip Setting the WINAPI_FAMILY directive to WINAPI_PARTITION_APP during
compilation removes the declarations of some Win32 functions and data types, but it
doesn't affect the linking step. You can reintroduce
some of the missing declarations in a temporary
toremove.h header file and then work to eliminate
references to those functions one at a time. A
temporary header file is also a good way to work
around the fact that the compiler stops after
encountering approximately 100 errors.

In some cases, you can resolve incompatibilities by
using functions from the C++ run-time library and STL.
In general, use standard C++ whenever
possible. Refactor core logic to use C++ libraries to
operate on containers, buffers, and so on. There are many new features in C++ 11 libraries, such as threads, mutexes, and I/O. Be sure to look in the C++ libraries when checking for a replacement for a Win32 API in the C++ library.

Tip Isolate platform-specific code into abstractions to make porting easier.

The remaining code, which formed the core
of the cartoon effect image filter, didn’t make calls to
the Win32 API. It just consisted of
numerical functions that manipulated the pixels in the
image. The only real porting issues for Hilo were in
reconciling the various data formats for bitmaps. For
example, when encoding the image prior to saving it, we needed to reorder the color channels to
use the BGRA (blue/green/red/alpha) layout that is
required by Windows Runtime functions.

Replace synchronous library functions with async versions

After your code compiles and runs using only data
types and functions that are available to Windows Store apps, review your code
for synchronous library functions that have
asynchronous versions available. Refactor the code to
consume aysnc operations if it doesn't already do
so. Your app should use the async approach whenever
possible.

Tip Refactor code to deal with partial
data. In cases where partial results are available
incrementally, make these results available to the
user without delay.

Tip Keep the UI responsive during async
operations.

In Hilo, we needed to convert the functions of the
original cartoon effect image filter code that loaded the image to be
processed to async versions.

Convert long running operations in your code to async versions

If your code has long running operations, consider
making these operations asynchronous. An easy way to do this
is to schedule long running work on the thread pool, for
example, by using a PPL task. You can rewrite code or
write a wrapper that runs existing code in thread
pool.

In Hilo, we used a PPL continuation task that runs in
the thread pool for the ported cartoon effect image
filter.

Validate the package with the Windows App Certification Kit

After you have changed your code to use only the
functions that are documented in the API reference for
Windows Store apps, the final porting step
is to create a package using app binaries and then to
use the Windows App Certification Kit tool to check
that the package is compliant with all the
requirements of the Windows Store. The package
contains all the app’s components, including static
libraries and DLLs.

Porting from Win32-based UI

If you have existing code that uses UI functions and
data types, such as HWND,
from User, GDI, or MFC, you’ll need to reimplement
that code using
XAML.

Porting DirectX

DirectX is available in Windows Store apps. If you use DirectX 11, most code ports
easily. Use a Visual Studio template for a DirectX
project as a starting point. When you initialize a Windows Store app at run time, there is some DirectX setup
required. The Visual Studio template sets up this startup code
for you. Move your existing code into the new
project.

Porting MFC

MFC is not available in Windows Store apps. To replace MFC UI classes, use XAML or
DirectX. For dialog apps, you can use XAML data
controls with data binding. To replace MFC utility
classes such as containers, use STL and C
run-time (CRT) data types.

Using the C++ run-time library (CRT)

A large subset of the CRT is available for Windows Store apps. There are a few functions
that aren't available.

Note Use the compiler preprocessor directive WINAPI_FAMILY=WINAPI_PARTITION_APP
to help find incompatibilities.

Some CRT functions that are available to Windows Store apps are blocking I/O functions. We
recommend that you replace synchronous I/O functions,
such as open, read, and write, with async equivalents from
the Windows Runtime.

ANSI string functions of the CRT are available in
Windows Store apps, but we recommend that
you use Unicode strings.

Using the C++ Standard Library

Nearly all functions and data types of the C++ Standard Library are
available in Windows Store apps (console
I/O is not available.) We use the C++ Standard Library extensively in
Hilo.

Using ATL

A subset of the ATL library is available in
Windows Store apps. Here are the available data types.

DLL server.

COM
objects. You can create your own COM
objects. However, IDispatch isn't
supported.

CStringW. Only wide
strings are supported.

ATL container
classes. MFC containers such as map that were
ported to ATL are still available.

Port all existing code, including libraries

Your app’s package must include all the binary
components that your app needs. This includes static
libraries and DLLs.

Link to static libraries or import libraries as usual

You can use libraries that are written in standard
C++ in your Windows Store app. Windows Store apps use the same linking as desktop and
console apps. If you have binary dependencies, it is important to validate your application package early in the development process so that all library functionality meets the requirements.

Note Although the CartoonEffect library does not directly use any Windows Runtime features, we did need to specify the /ZW (Consume Windows Runtime Extension) compiler option because the PPL version of the cartoon effect algorithm uses special semantics in Windows Store apps (for example, in a Windows Store app, you can configure the context on which PPL task continuations run.)

Use C++/CX or WRL if your library needs to invoke Windows Runtime functions

If your library needs to invoke Windows Runtime functions,
you can use either C++/CX or WRL. In
general terms, C++/CX is easier to use. WRL
gives you more fine-grained control.

Note There are some technical issues with exposing
public reference classes from within a user-written
library. This is outside of the scope of this
guide.

Convert to Windows Runtime types when marshaling cost is an issue

Use Windows Runtime types for objects that
frequently cross the ABI boundary and are costly to
convert.

You can use String and Array, which can be efficiently converted
without copying, as input parameters to
the Windows Runtime API. StringReference and ArrayReference add a Windows Runtime veneer using borrow semantics.

For containers and collection types, the conversion
from std::* to Platform::* requires
copying. In general, the containers and collections of
the std namespace are more efficient than the
containers and collections of the Platform namespace.
When to use each of these depends on how often
collection contents change compared to how often they
cross the ABI.

In Hilo, we spent a lot of time deciding when to
use public ref classes. For our application, we found
that the overhead of type conversion outweighed other
concerns.

Decide between using wrapper code and converting existing code

If you have existing code that needs to be called across the ABI, you must decide whether to port that code to C++/CX or leave it in standard C++ and wrap it with a C++/CX layer. In most situations we recommend using a wrapper layer.

Converting existing code and making it use Windows Runtime
types and concepts is normally only done to avoid data conversion overhead, for example, when your component must be called very frequently across the ABI. These situations are rare.

If you decide to create a C++/CX wrapper for your classes, the standard way to do this is to define interfaces and in their implementation delegate
to your existing C++ code, after any necessary type
conversions. Using interfaces in this way creates a Windows Runtime veneer over
your existing code and is sufficient for most cases.

If you have existing COM components, consider exposing them
as Windows Runtime types. Doing this makes it easy for Windows Store apps to consume your COM
objects. The techniques required to do this are outside the scope
of this guide.