Effective WinRT with C++Tips and tricks for developing WinRT applications in C++
Effective WinRT with C++
• How WinRT works with C++
• Thread safety▫Thread-safe singletons▫Using lambdas for callbacks
Using the PPL Exception handling
• General hints with WinRT▫Error handling for permissions▫Using delegates for callbacks
How WinRT works with C++
•C++ implementation choices:▫XAML based.▫DirectX (Direct2D and/or Direct3D) based.▫A subset of win32 API is available.
•Windows Store apps are sandboxed, so there are some limitations.▫Disk and hardware access is restricted.▫Fully multithreaded design.
Using C++ to implement WinRT classes
• public interface:▫WinRT types and conventions only.
• private (or internal) interface:▫Standard C++ containers, classes and
conventions can be used.
•Enumerated types:▫Strongly typed enums (enum class) are accepted.
Using new standard language features
• WinRT containers can be constructed from standard library containers.
• Range-based for loops work with WinRT classes (include collection.h).
• Move semantics is available.
• Lambdas are accepted as delegates/function pointers.
• Thread safety is very important.
Thread safety in modern C++•Example of a thread-safe singleton
class Singleton{public: virtual ~Singleton(); static Singleton& Get();
private: static std::unique_ptr<Singleton> s_instance; static std::once_flag s_creationFlag;
Singleton(); Singleton(const Singleton& other) /* = delete */; Singleton& operator=(const Singleton& other) /* = delete */;}
Thread safety in modern C++•Example of a thread-safe singleton
std::unique_ptr<Singleton> Singletion::s_instance = nullptr;std::once_flag Singleton::s_creationFlag;
Singleton& Singleton::Get(){ std::call_once(s_creationFlag, []{ s_instance.reset(new Singleton); }); return *s_instance.get();}
Multithreading in WinRT
• Every command* runs in its own thread.
• Avoid the callback spaghetti:
▫Parallel Patterns Library
▫Use delegates for event handling
* That potentially lasts longer than 50 ms
Parallel Patterns Library
The Parallel Patterns Library (PPL) provides an imperative programming model that promotes scalability and ease-of-
use for developing concurrent applications.
- MSDN (http://msdn.microsoft.com/en-us/library/dd492418.aspx)
Parallel Patterns Library• Task objects, analogous to std::future objects.using namespace concurrency;
task<void> myTask([]{ do_something(); });auto myTask = concurrency::create_task([]{ do_something(); });
// Non-blocking or blocking call to retrieve the resultmyTask.get();
// Blocking call, retrieves the statusmyTask.wait();
• Allows an imperative style when launching non-blocking tasks
myTask.then([]{ do_what_comes_next(); });
Asynchronous calls made easyconcurrency::task<void> Singleton::ComplexTask(){ /* ... */ }
// Define a sequence of tasksSingleton::Get().ComplexTask() .then([] { // ... }) .then([] { // ... });
WinRT CoreDispatcher class•Every XAML page can access the CoreDispatcher
object through the Dispatcher member
•Issue tasks in the main thread, from any thread.
using namespace Windows::Core::UI;using namespace Windows::System::Threading;
// Non-blocking call with normal priority.Dispatcher->RunAsync(CoreDispatcherPriority::Normal, ref new DispatchedHandler([]{ /*...*/ }));
// Check whether the current thread can be accessed Dispatcher->HasThreadAccess();
Capturing objects in task chains
concurrency::task<void> MyClass::ExecuteTask(){ // ... return concurrency::create_task( [this, local_variable] // <-- avoid locals by reference! { m_cached_value = local_variable; }) .then([this] { }); // and so on...};
Exception handlingconcurrency::create_task([] { }) // A few tasks “later”... .then([this](concurrency::task<void> t) { try { t.get(); } catch(Platform::Exception^ except) { // Handle except } });
Special cases in error handling•Handle connection to devices
▫Windows handles first access for you. Geolocation, camera, phone functionality, etc.
•When using webcam or microphone▫Permission errors are handled by checking:
E_ACCESSDENIED HRESULT_FROM_WIN32(ERROR_FILE_HANDLE_REVOKED)
•When sending SMS (Windows Phone 8)▫Permission errors handled by checking:
E_ACCESSDENIED
Special cases in error handling• Examples of error handling for webcam capture
▫Initialization error: // (continued task chain including call to InitializeAsync) .then([this](task<void> t) { try { t.get(); } catch(Exception^ e) { if(e->HResult == E_ACCESSDENIED) // Handle permissions error else // Check if camera is not connected } }
▫Spontaneous error: void CameraCallback(MediaCapture^ currentCaptureObject, MediaCaptureFailedEventArgs^ currentFailure) { if(currentFailure->Code == HRESULT_FROM_WIN32(ERROR_FILE_HANDLE_REVOKED)) // Handle revoked permissions else // Check if camera was suddenly disconnected }
Special cases in error handling
Short Demonstration
Granting permissions
•File system access may be needed for logging
▫Add the targeted folder read/write access to ALL APPLICATION PACKAGES
Using delegates for callbacks•In WinRT applications, callbacks can be
registered through a generic mechanism.
•Non-standard language extensions:▫delegate keyword.▫event keyword.
•WinRT EventRegistrationToken class:▫Used to register the delegates for
corresponding events.
Using delegates for callbacks
•A very simple class that reacts to eventspublic delegate void MyEventHandler();
public ref class MyEventsManager sealed{public: static event MyEventHandler^ OnMyEvent; static void FireMyEvent() { OnMyEvent(); }};
Using delegates for callbacks• Use EventRegistrationToken// Class declarationclass MyClass{// ...private: Windows::Foundation::EventRegistrationToken token;}
// Class implementation
token = MyEventsManager::OnMyEvent += ref new MyEventHandler([]{ /* ... */ });
• Finally, trigger the event when needed by calling MyEventsManager::FireMyEvent();
Using delegates for callbacks
Short Demonstration
References and useful sources
• ISO Standard C++ official page▫ http://www.isocpp.org/
• MSDN (Microsoft Developer Network)▫ http://msdn.microsoft.com/library/windows/apps/
• CodeProject▫ http://www.codeproject.com/Articles/472009/Creating-Windows-
Store-app-Beginners-tutorial
• Marc Grégoire Blog▫ http://www.nuonsoft.com/blog/
Thank you