windows 8 and winrt from a c++ perspective
DESCRIPTION
Windows 8 and WinRT from a C++ perspective. Marc Grégoire. Who am I?. Marc Grégoire MVP VC++ / Microsoft MEET member [email protected] http://www.nuonsoft.com/blog/ Founder of the Belgian C++ Users Group (BeCPP) http://becpp.org/. Agenda. Windows 8 Platform - PowerPoint PPT PresentationTRANSCRIPT
#comdaybe
Windows 8 and WinRT froma C++ perspective
Marc Grégoire
Who am I?
• Marc Grégoire• MVP VC++ / Microsoft MEET member• [email protected]• http://www.nuonsoft.com/blog/• Founder of the Belgian C++ Users Group
(BeCPP)• http://becpp.org/
Agenda
• Windows 8 Platform• Windows Runtime (WinRT)• C++ Extensions (C++/CX)• Asynchronous programming model• Libraries (WinRT STL)• C++ and XAML
Windows 8 Platform
Windows 8 Platform
Windows Core OS Services
JavaScript(Chakra)
C#VB
Metro style Apps
Communication & Data
Application Model
Devices & Printing
Windows Runtime APIs
Graphics & Media
XAML HTML / CSS
HTMLJavaScrip
t
CC++
C#VB
Desktop Apps
Win32
.NET / SL
Internet Explorer
CC++
Syste
m S
erv
ices
Vie w
Mod
el
Con
troll
er
Core
CC++
XAML
Windows 8 Platform – Where C++?
• Metro Hybrid Apps– HTML5 + JavaScript front-end– C++ components
• Metro XAML Apps– UI using XAML– C++ code behind
• Metro high performance 2D/3D Apps– C++ with DirectX rendering
Windows Runtime (WinRT)
Windows Runtime (WinRT)
• Foundation for building Metro style apps– Strongly-typed system– Automatically reference counted– Exception-based– Well defined binary contract across module
boundaries, ABI-safe– (For C++) Deep integration with STL
Windows Runtime (WinRT)
• Contains classes for UI, Pickers, Controls, Media, XAML, Storage, Network, …
• A subset of the Win32 APIs can still be used
Windows Runtime (WinRT)
DevicesSenso
rsGeolocati
onPortable
NFC
Communications & DataContract
s
XML
Web
SMSNetworki
ng
Notifications
Local & Cloud Storage
StreamsBackground
Transfer
User InterfaceHTML5/CSS XAML DirectX Controls
InputAccessibilit
yPrinting
Data Binding
TilesSVG
FundamentalsApplication
ServicesAuthentica
tionCryptograp
hyGlobaliza
tionMemory
ManagementThreading/
Timers
MediaVisual Effects
Playback
PlayTo
Capture
Windows Runtime (WinRT)
• Includes detailed metadata = complete description of the Windows Runtime
• Metadata allows projection into different languages: C++, C#, VB, JavaScript
C++ Extensions (C++/CX)
C++ Extensions (C++/CX)
• Set of language extensions and libraries to allow direct consumption and authoring of WinRT types
C++ Extensions (C++/CX)Key Bindings Feature Summary
1. Data Types ref class Reference type
value class Value type
interface class Interface
property Property with get/set
event “Delegate property” with add/remove/raise
delegate Type-safe function pointer
generic Type-safe generics
2. Allocation ref new Reference-counted allocation
3. Pointer & Reference
^ Strong pointer (“hat” or “handle”)
% Strong reference
C++ Extensions (C++/CX)
ModuleInternals
written in C++
WinRT External Surface
for WinRT callers/callee
s
C/C++ External Surface
for native callers/callees
Automatic Lifetime Management• Handle (^ / Hat) is smart pointer to WinRT
objects• Reference counted• Allocated with ref new• Example:
Person^ p;{ Person^ p2 = ref new Person(); // ref count = 1 p2->Name = "John"; // ref count = 1 p = p2; // ref count = 2} // ref count = 1p = nullptr; // ref count = 0 ~Person()
Automatic Lifetime Management• Even easier…• Simply on the stack, or as a
member of another WinRT type• Example:
{ Person p; p.Name = "John"; /* ... */} // ~Person()
WinRT Class
• Use ref class to define new WinRT classes (ABI-safe cross-language classes)
• Example:public ref class Person{ public: Person(String^ name, String^ email); void Greet(Person^ other);
internal: ~Person(); void SetPassword(const std::wstring& passwd);};
Public/protected methods only WinRT parameters
Private/internal methods any C++ types as parameters
Usage:Person^ p = ref new Person("John", "[email protected]");p->Greet(ref new Person("Jim"));
WinRT Interface
• Definingpublic interface class IShape{ void Draw();};
• Inheritingpublic interface class ISelectableShape : IShape{ void Select();};
• Implementingref class Rectangle : ISelectableShape{ public: virtual void Draw(); virtual void Select();};
• UsingIShape^ shape = ref new Rectangle();shape->Draw();
WinRT Property• Defining– Trivial properties (with private backing store)public: property String^ Name;
– User defined propertiespublic: property Person^ Sibling { Person^ get() { InitSiblings(); return _sibling; } void set(Person^ value) { _sibling = value; NotifySibling(); } }private: Person^ _sibling;
• UsingPerson^ p = ref new Person("John");p->Sibling = ref new Person(p->Name);
WinRT Delegate• Declaring
public delegate void PropertyChanged(String^ propName, String^ propValue);
• Instantiating– From lambda:auto p = ref new PropertyChanged( [](String^ pn, String^ pv) { cout << pn << " = " << pv; });
– From free-functionauto p = ref new PropertyChanged(UIPropertyChanged);
– From class-memberauto p = ref new PropertyChanged(this, MainPage::OnPropertyChanged);
• Invokingp("Visible", "f");
WinRT Event
• Defining–Trivial event (with private backing
store)public: event PropertyChanged^ OnPropertyChanged;
–User defined propertiespublic: event PropertyChanged^ OnNetworkChanged { EventRegistrationToken add(PropertyChanged^); void remove(EventRegistrationToken t); void raise(String^, String^);}
WinRT Event
• Using–Subscribingperson->OnPropertyChanged += propertyChangedDelegate;auto token = person->OnPropertyChanged::add(propertyChangedDelegate);
– Unsubscribingperson->OnPropertyChanged -= token;person->OnPropertyChanged::remove(token);
WinRT Exceptions
• Under the covers, WinRT uses COM, thus HRESULTs
• WinRT wraps HRESULTs into exceptions
WinRT Exceptions
• Only a fixed set of exceptions is available• Platform::Exception is the
base for all WinRTexceptions
• You cannot derive your ownexceptions fromPlatform::Exception
HRESULT Exception
E_OUTOFMEMORY OutOfMemoryException
E_INVALIDARG InvalidArgumentException
E_NOINTERFACE InvalidCastException
E_POINTER NullReferenceException
E_NOTIMPL NotImplementedException
E_ACCESSDENIED AccessDeniedException
E_FAIL FailureException
E_BOUNDS OutOfBoundsException
E_CHANGED_STATE ChangedStateException
REGDB_E_CLASSNOTREG
ClassNotRegisteredException
E_DISCONNECTED DisconnectedException
E_ABORT OperationCanceledException
WinRT Exceptions
• Throwing exceptionsthrow ref new InvalidArgumentException();throw ref new COMException(hr);
• Catching exceptionstry { … } catch (OutOfMemoryException^ ex) { … }
• Catch all WinRT exceptions:catch (Platform::Exception^ ex) { }
• Access HRESULT via ex->HResult
WinRT Generics
• Defininggeneric<typename T, typename U> public interface class IPair {
property T First;property U Second;
};
• Implementingref class PairStringUri: IPair<String^, Uri^> {public:
property String^ First;property Uri^ Second;
};
• UsingIPair<String^, Uri^>^ uri = ref new PairStringUri();auto first = uri->First; // String^auto second = uri->Second; // Uri^
WinRT .winmd Metadata Files• .winmd files
– Contain the metadata representation of WinRT types
• To consume a winmd file:– Right click on project in Solution Explorer > References > Add New
Reference… Or– #using <Company.Component.winmd>– Make sure the winmd and implementation dll is packaged together with
your application
• To produce a .winmd file:– Start from the “C++ WinRT Component Dll” template– Define public types (ref classes, interfaces, delegates, etc.)
WinRT Partial Runtime Classes• Partial class definition
partial ref class MainPage: UserControl, IComponentConnector{public: void InitializeComponent(); void Connect() { btn1->Click += ref new EventHandler(this, &MainPage::Button_Click); }};
• Class definitionref class MainPage{public: MainPage() { InitializeComponent(); } void Button_Click(Object^ sender, RoutedEventArgs^ e);};
Async
Asynchronous programming model
Async with PPL Tasks• Windows 8 Metro only allows asynchronous
operations for anything that can take longer than a couple milliseconds
• For example: there are no synchronous file operations possible in Metro
• Advantage: keeps UI fast and fluid• Disadvantage: programming can be more
complex, but new PPL tasks support helps alot here
Async with PPL Tasks
• Example:– Create a file– Open the file– Write a string to the file– Flush the file
33
StorageFolder^ item = KnownFolders::PicturesLibrary;auto createStorageFileOp = item->CreateFileAsync("myfile.txt");createStorageFileOp->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>( [](IAsyncOperation<StorageFile^>^ asyncOp, AsyncStatus status) { auto streamRetrievalOp = asyncOp->GetResults()->OpenAsync(FileAccessMode::ReadWrite); streamRetrievalOp->Completed = ref new AsyncOperationCompletedHandler<IRandomAccessStream^>( [](IAsyncOperation<IRandomAccessStream^>^ asyncOp, AsyncStatus status) { IOutputStream^ stream = asyncOp->GetResults()->GetOutputStreamAt(0); DataWriter^ bbrw = ref new DataWriter(stream); bbrw->WriteString("Hello async!"); auto writeBinaryStringOp = bbrw->StoreAsync(); writeBinaryStringOp->Completed = ref new AsyncOperationCompletedHandler<unsigned int>( [stream](IAsyncOperation<unsigned int>^ asyncOp, AsyncStatus status) { int bytes = asyncOp->GetResults(); auto streamFlushOp = stream->FlushAsync(); streamFlushOp->Completed = ref new AsyncOperationCompletedHandler<bool>( [](IAsyncOperation<bool>^ asyncOp, AsyncStatus status) { bool result = asyncOp->GetResults(); }); }); }); });
Without PPL Tasks
34
StorageFolder^ item = KnownFolders::PicturesLibrary;auto createStorageFileOp = item->CreateFileAsync("myfile.txt");task<StorageFile^> createFileTask(createStorageFileOp);IOutputStream^ ostream;
createFileTask.then([](StorageFile^ storageFile){ return storageFile->OpenAsync(FileAccessMode::ReadWrite);}).then([](IRandomAccessStream^ rastream) -> task<bool> { ostream = rastream->GetOutputStreamAt(0); DataWriter^ bbrw = ref new DataWriter(ostream); bbrw->WriteString("Hello async!"); return bbrw->StoreAsync();}).then([ostream](unsigned int bytesWritten) { return ostream->FlushAsync();}).then([](bool flushed) {});
With PPL Tasks
Libraries (WinRT STL)
Vector and ObservableVector• Instantiating
using namespace Platform::Collections;Vector<String^>^ items = ref new Vector<String^>();
• Adding elementsitems->Append("Hello");
• Returning a read-only view of the vectorIVectorView<String^>^ view = items->GetView();
• Getting notification for changesitems->VectorChanged += ref new VectorChangedEventHandler<String^> (this, &MyClass::VectorChanged);
Map and ObservableMap• Defining
using namespace Platform::Collections;auto favorites = ref new Map<String^, Uri^>();
• Adding elementsfavorites->Insert("MSDN", ref new Uri("http://msdn.com"));
• Checking and removing elementsif (favorites->HasKey("MSDN")) favorites->Remove("MSDN");
Integration with STL Algorithms• WinRT String has Begin()/End() member methods• For WinRT collections, collection.h defines begin()
and end() functions• Example:
IVector<int>^ v = GetItems();int sum = 0;std::for_each(begin(v), end(v), [&sum](int element) { sum += element; });
Integration with STL Containers• Conversion is possible between STL containers and
WinRT containers• String^ std::wstring (via wchar_t*)• Vector std::vector
std::vector<int> v;v.push_back(10);auto items = ref new Vector<int>(v);
• Vector std::vectorVector<int>^ items = ...;std::vector<int> v = Windows::Foundation::Collections::to_vector(items);
C++ and XAML
Windows 8 Platform – Where C++?
• Metro Hybrid Apps– HTML5 + Javascript front-end– C++ components
• Metro XAML Apps– UI using XAML– C++ code behind
• Metro high performance 2D/3D Apps– C++ with DirectX rendering
• Metro Hybrid Apps– HTML5 + Javascript front-end– C++ components
• Metro XAML Apps– UI using XAML– C++ code behind
• Metro high performance 2D/3D Apps– C++ with DirectX rendering
demoC++ and XAML
Resources
• “Using Windows Runtime With C++” – Herb Sutter– http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-532T
• “Building Windows Metro style apps in C++/XAML” – Vikas Bhatia, Joanna Mason– http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-479T
Belgian C++ Users Group (BeCPP)
http://BeCPP.org/
Aim? quarterly meetings
Audience? free for everyone
Where? at Microsoft offices in Zaventem or at sponsor
company locations (we’re still looking for hosts / sponsors!)
Become a member? http
://becpp.org/blog/become-a-member/
Announcements? become member or subscribe to our blog
Questions? [email protected]
Belgian C++ Users Group (BeCPP)• Next meeting: June 27th 2012• Agenda with top international speakers:– Session 1: What’s new in VC++ 2012 (Rong Lu)– Break– Session 2: C++ AMP (GPGPU Computing) (Kate
Gregory)– Drink
• Register Now: http://becpp-june.eventbrite.com/
Q&A
Thank you!I would like to thank Herb Sutter from Microsoft for his permission to base this presentation on one
that he wrote.