Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
När efterföljande versioner av C++/WinRT släpps beskriver det här avsnittet vad som är nytt och vad som har ändrats.
Sammanslagning av de senaste förbättringarna/tilläggen från och med mars 2020
Upp till 23% kortare byggtider
Kompilatorteamen C++/WinRT och C++ har samarbetat för att göra allt som är möjligt för att förkorta byggtiderna. Vi har gått igenom kompileringsanalyser för att ta reda på hur de interna funktionerna i C++/WinRT kan omstruktureras för att hjälpa C++-kompilatorn att eliminera kompileringstiden, samt hur själva C++-kompilatorn kan förbättras för att hantera C++/WinRT-biblioteket. C++/WinRT har optimerats för kompilatorn. och kompilatorn har optimerats för C++/WinRT.
Vi tar till exempel det värsta scenariot med att skapa en förkompilerad rubrik (PCH) som innehåller varje C++/WinRT-projektionsnamnområdesrubrik.
| Utgåva | PCH-storlek (byte) | Tid (s) |
|---|---|---|
| C++/WinRT från juli, med Visual C++ 16.3 | 3,004,104,632 | 31 |
| version 2.0.200316.3 av C++/WinRT, med Visual C++ 16.5 | 2,393,515,336 | 24 |
En minskning på 20% i storlek och en minskning på 23% i byggtid.
Förbättrat MSBuild-stöd
Vi har investerat mycket arbete för att förbättra MSBuild-stödet för ett stort urval av olika scenarier.
Ännu snabbare cache hantering för fabrik
Vi har förbättrat inlinjeringen av cacheminnet för att bättre inlinjera kritiska vägar, vilket leder till snabbare exekvering.
Den här förbättringen påverkar inte kodstorleken– enligt beskrivningen nedan i /d2FH4, om ditt program använder C++-undantagshantering kraftigt kan du krympa din binära fil med hjälp av alternativet som är aktiverat som standard i nya projekt som skapats med Visual Studio 2019 16.3 och senare.
Effektivare boxning
När det används i en XAML-applikation är winrt::box_value nu mer effektiv (se boxning och avboxning). Program som gör mycket boxning kommer också att märka en minskning av kodstorleken.
Stöd för att implementera COM-gränssnitt som implementerar IInspectable
Om du behöver implementera ett (icke-Windows-Runtime) COM-gränssnitt som bara råkar implementera IInspectable kan du nu göra det med C++/WinRT. Se COM-gränssnitt som implementerar IInspectable.
Förbättringar av modullåsning
Kontroll över modullåsning tillåter nu både anpassade värdscenarier och eliminering av låsning på modulnivå helt och hållet. Se förbättringar av modullåsning .
Stöd för information om fel som inte ärWindows-Runtime
Vissa API:er (även vissa Windows Runtime-API:er) rapporterar fel utan att använda Windows Runtime-felhanterings-API:er. I så fall återgår C++/WinRT nu till att använda COM-felinformation. Se C++/WinRT-stöd för icke-WinRT-felinformation.
Aktivera stöd för C++-moduler
Stöd för C++-modulen är tillbaka, men endast i experimentell form. Funktionen har ännu inte slutförts i C++-kompilatorn.
Effektivare coroutine-återupptagande
C++/WinRT-coroutines fungerar redan bra, men vi fortsätter att leta efter sätt att förbättra det. Se Förbättra skalbarheten för återupptagning av korutiner.
Nya asynkrona hjälpverktyg för when_all och when_any
Hjälpfunktionen when_all skapar ett IAsyncAction- objekt som slutförs när alla de angivna väntbara objekten har slutförts. when_any-hjälpfunktion skapar en IAsyncAction- som slutförs när något av de angivna väntbara objekten har slutförts.
Se Lägg till when_any asynkron hjälpfunktion och Lägg till when_all asynkron hjälpfunktion.
Andra optimeringar och tillägg
Dessutom har många felkorrigeringar och mindre optimeringar och tillägg introducerats, inklusive olika förbättringar för att förenkla felsökning och optimera interna implementeringar och standardimplementeringar. Följ den här länken för en fullständig lista: https://github.com/microsoft/xlang/pulls?q=is%3Apr+is%3Aclosed.
Nyheter och ändringar i C++/WinRT 2.0
Mer information om C++/WinRT Visual Studio-tillägget (VSIX), Microsoft.Windows.CppWinRT NuGet-paketet och cppwinrt.exe verktyget – inklusive hur du hämtar och installerar dem – finns i Visual Studio-stöd för C++/WinRT, XAML, VSIX-tillägget och NuGet-paketet.
Ändringar i C++/WinRT Visual Studio-tillägget (VSIX) för version 2.0
- Felsökningsvisualiseraren stöder nu Visual Studio 2019. samt fortsätta att stödja Visual Studio 2017.
- Många felkorrigeringar har gjorts.
Ändringar i NuGet-paketet Microsoft.Windows.CppWinRT för version 2.0
- Verktyget
cppwinrt.exeingår nu i NuGet-paketet Microsoft.Windows.CppWinRT och verktyget genererar platfomprojektionshuvuden för varje projekt på begäran. Därförcppwinrt.exeär verktyget inte längre beroende av Windows SDK (även om verktyget fortfarande levereras med SDK av kompatibilitetsskäl). -
cppwinrt.exegenererar nu projekthuvuden under varje plattforms-/konfigurationsspecifik mellanliggande mapp ($IntDir) för att möjliggöra parallella byggen. - C++/WinRT-byggstöd (rekvisita/mål) är nu helt dokumenterat, om du vill anpassa dina projektfiler manuellt. Se NuGet-paketet Microsoft.Windows.CppWinRT readme.
- Många felkorrigeringar har gjorts.
Ändringar i C++/WinRT för version 2.0
Öppen källkod
Verktyget cppwinrt.exe tar en Windows Runtime-metadatafil (.winmd) och genererar från den ett huvudfilbaserat C++-standardbibliotek som projekt API:erna som beskrivs i metadata. På så sätt kan du använda dessa API:er från din C++/WinRT-kod.
Det här verktyget är nu ett helt projekt med öppen källkod som är tillgängligt på GitHub. Besök Microsoft/cppwinrt.
xlang-bibliotek
Ett helt portabelt huvudbibliotek (för parsning av ECMA-335-metadataformatet som används av Windows Runtime) utgör grunden för alla Windows Runtime- och xlang-verktyg framöver. Framför allt skriver vi också om cppwinrt.exe verktyget från grunden med hjälp av xlang-biblioteken. Detta ger mycket mer exakta metadatafrågor och löser några långvariga problem med C++/WinRT-språkprojektionen.
Färre beroenden
På grund av xlang-metadataläsaren cppwinrt.exe har själva verktyget färre beroenden. Detta gör det mycket mer flexibelt och kan användas i fler scenarier, särskilt i begränsade byggmiljöer. I synnerhet förlitar den sig inte längre på RoMetadata.dll.
Det här är beroendena för cppwinrt.exe 2.0.
- ADVAPI32.dll
- KERNEL32.dll
- SHLWAPI.dll
- XmlLite.dll
Alla dessa DLL:er är tillgängliga inte bara på Windows 10, utan hela vägen ner till Windows 7 och till och med Windows Vista. Om du vill kan din gamla byggserver som kör Windows 7 nu köra cppwinrt.exe för att generera C++-rubriker för ditt projekt. Med lite arbete kan du till och med köra C++/WinRT på Windows 7, om det intresserar dig.
Jämför listan ovan med dessa beroenden, som cppwinrt.exe 1.0 har.
- ADVAPI32.dll
- SHELL32.dll
- api-ms-win-core-file-l1-1-0.dll
- XmlLite.dll
- api-ms-win-core-libraryloader-l1-2-0.dll
- api-ms-win-core-processenvironment-l1-1-0.dll
- RoMetadata.dll
- SHLWAPI.dll
- KERNEL32.dll
- api-ms-win-core-rtlsupport-l1-1-0.dll
- api-ms-win-core-heap-l1-1-0.dll
- api-ms-win-core-timezone-l1-1-0.dll
- api-ms-win-core-console-l1-1-0.dll
- api-ms-win-core-localization-l1-2-0.dll
- OLEAUT32.dll
- api-ms-win-core-winrt-error-l1-1-0.dll
- api-ms-win-core-winrt-error-l1-1-1.dll
- api-ms-win-core-winrt-l1-1-0.dll
- api-ms-win-core-winrt-string-l1-1-0.dll
- api-ms-win-core-synch-l1-1-0.dll
- api-ms-win-core-threadpool-l1-2-0.dll
- api-ms-win-core-com-l1-1-0.dll
- api-ms-win-core-com-l1-1-1.dll
- api-ms-win-core-synch-l1-2-0.dll
Windows Runtime-attributet noexcept
Windows Runtime har ett nytt [noexcept] attribut som du kan använda för att dekorera dina metoder och egenskaper i MIDL 3.0. Förekomsten av attributet anger för stödverktyg att implementeringen inte utlöser ett undantag (eller returnerar en misslyckad HRESULT). Detta gör att språkprojektioner kan optimera kodgenerering genom att undvika de undantagshanteringskostnader som krävs för att stödja ABI-anrop (Application Binary Interface) som potentiellt kan misslyckas.
C++/WinRT drar nytta av detta genom att producera C++ noexcept -implementeringar av både den förbrukande koden och redigeringskoden. Om du har API-metoder eller egenskaper som inte är felfria och du är orolig för kodstorleken kan du undersöka det här attributet.
Optimerad kodgenerering
C++/WinRT genererar nu ännu effektivare C++-källkod (bakom kulisserna) så att C++-kompilatorn kan producera den minsta och mest effektiva binära koden som möjligt. Många av förbättringarna är inriktade på att minska kostnaderna för undantagshantering genom att undvika onödig upprullningsinformation. Binärfiler som använder stora mängder C++/WinRT-kod ser ungefär 4% minskning av kodstorleken. Koden är också effektivare (den körs snabbare) på grund av det minskade antalet instruktioner.
Dessa förbättringar är beroende av en ny interop-funktion som också är tillgänglig för dig. Alla typer av C++/WinRT som är resursägare innehåller nu en konstruktor för direkt ägande, vilket undviker den tidigare tvåstegsmetoden.
ABI::Windows::Foundation::IStringable* raw = ...
IStringable projected(raw, take_ownership_from_abi);
printf("%ls\n", projected.ToString().c_str());
Optimerad kodgenerering för undantagshantering (EH)
Den här ändringen kompletterar arbete som har utförts av Microsoft C++-optimerarteamet för att minska kostnaden för undantagshantering. Om du använder binärt gränssnitt (API:er) (t.ex. COM) kraftigt i koden ser du mycket kod som följer det här mönstret.
int32_t Function() noexcept
{
try
{
// code here constitutes unique value.
}
catch (...)
{
// code here is always duplicated.
}
}
Själva C++/WinRT genererar det här mönstret för varje API som implementeras. Med tusentals API-funktioner kan alla optimeringar här vara betydande. Tidigare kunde optimeraren inte upptäcka att alla dessa fångstblock är identiska, så det duplicerade mycket kod runt varje ABI (vilket i sin tur bidrog till tron att användning av undantag i systemkod ger stora binärfiler). Men från och med Visual Studio 2019 konsoliderar C++-kompilatorn alla dessa catch-funktioner och lagrar bara de som är unika. Resultatet är ytterligare 18% minskning av kodstorleken för binärfiler som är starkt beroende av det här mönstret. Eh-koden är inte bara effektivare nu än att använda returkoder, utan även oron för större binärfiler är nu något av det förflutna.
Förbättringar av inkrementellt bygge
Verktyget cppwinrt.exe jämför nu utdata från en genererad rubrik/källfil med innehållet i en befintlig fil på disken och skriver bara ut filen om filen faktiskt har ändrats. Detta sparar mycket tid med disk-I/O och säkerställer att filerna inte betraktas som "smutsiga" av C++-kompilatorn. Resultatet är att omkompilering undviks, eller minskas, i många fall.
Allmänna gränssnitt genereras nu
På grund av xlang-metadataläsaren genererar C++/WinRT nu alla parametriserade eller generiska gränssnitt från metadata. Gränssnitt som Windows::Foundation::Collections::IVector<T> genereras nu från metadata i stället för handskrivna i winrt/base.h. Resultatet är att winrt/base.h har fått sin storlek halverad och att optimeringar genereras direkt i koden (vilket var svårt att göra med den handgjorda metoden).
Viktigt!
Gränssnitt som exemplet som anges visas nu i respektive namnområdesrubriker i stället för i winrt/base.h. Om du inte redan har gjort det måste du inkludera rätt namnområdesrubrik för att kunna använda gränssnittet.
Komponentoptimeringar
Den här uppdateringen lägger till stöd för flera ytterligare opt-in-optimeringar för C++/WinRT, som beskrivs i avsnitten nedan. Eftersom dessa optimeringar bryter mot ändringar (som du kan behöva göra mindre ändringar för att stödja), måste du aktivera dem explicit. I Visual Studio anger du projektegenskapen Vanliga egenskaper>C++/WinRT>Optimerad till Ja. Det innebär att du lägger till <CppWinRTOptimized>true</CppWinRTOptimized> i projektfilen. Och det har samma effekt som att lägga till växeln -opt[imize] när du anropar cppwinrt.exe från kommandoraden.
Ett nytt projekt (från en projektmall) kommer att använda -opt som standard.
Enhetlig konstruktion och direkt implementeringsåtkomst
Dessa två optimeringar ger din komponent direkt åtkomst till sina egna implementeringstyper, även om den bara använder de planerade typerna. Du behöver inte använda göra, make_selfeller get_self om du bara vill använda den offentliga API-ytan. Dina anrop kommer att kompileras ned till direkta anrop till implementeringen, och dessa kan till och med vara helt inlinade.
Mer information och kodexempel finns i Anmäl dig till enhetlig konstruktion och direkt implementeringsåtkomst.
Typraderade fabriker
Den här optimeringen undviker #include beroenden i module.g.cpp så att den inte behöver kompileras om varje gång någon enskild implementeringsklass ändras. Resultatet blir bättre byggprestanda.
Smartare och effektivare module.g.cpp för stora projekt med flera libs
Filen module.g.cpp innehåller nu även ytterligare två komposterbara hjälpverktyg med namnet winrt_can_unload_now och winrt_get_activation_factory. Dessa har utformats för större projekt där en DLL består av ett antal libs, var och en med sina egna körningsklasser. I så fall måste du manuellt sammanfoga DLL:ens DllGetActivationFactory och DllCanUnloadNow. De här hjälparna gör det mycket enklare för dig att göra det genom att undvika falska originationsfel. Verktygets cppwinrt.exe-lib flagga kan också användas för att ge varje enskilt bibliotek sin egen ingress (i stället för winrt_xxx) så att varje biblioteks funktioner kan namnges individuellt och därmed kombineras entydigt.
Coroutine-stöd
Coroutine-stöd ingår automatiskt. Tidigare fanns stödet på flera platser, vilket vi tyckte var för begränsande. Och tillfälligt för v2.0 var en winrt/coroutine.h rubrikfil nödvändig, men det behövs inte längre. Eftersom asynkrona Windows Runtime-gränssnitt nu genereras, i stället för handskrivna, finns de nu i winrt/Windows.Foundation.h. Förutom att vara mer underhållsbara och supportbara innebär det att koroutinhjälpare som resume_foreground inte längre behöver fästas på slutet av en specifik namnområdesrubrik. I stället kan de mer naturligt inkludera sina beroenden. På så sätt kan resume_foreground inte bara stödja återupptagande av en viss Windows::UI::Core::CoreDispatcher, utan kan nu även stödja återupptagande av en viss Windows::System::DispatcherQueue. Tidigare kunde endast en stödjas. men inte båda, eftersom definitionen bara kunde finnas i ett namnområde.
Här är ett exempel på DispatcherQueue-supporten .
...
#include <winrt/Windows.System.h>
using namespace Windows::System;
...
fire_and_forget Async(DispatcherQueueController controller)
{
bool queued = co_await resume_foreground(controller.DispatcherQueue());
assert(queued);
// This is just to simulate queue failure...
co_await controller.ShutdownQueueAsync();
queued = co_await resume_foreground(controller.DispatcherQueue());
assert(!queued);
}
Dessa Coroutine-hjälpare har nu också fått [[nodiscard]]för att förbättra deras användbarhet. Om du glömmer (eller inte inser att du måste) co_await dem för att de ska fungera, kommer sådana misstag nu att leda till en kompilatorvarning på grund av [[nodiscard]].
Hjälp med att diagnostisera direktallokeringar (stack)
Eftersom de projekterade klassnamnen och implementeringsklassnamnen (som standard) är desamma och bara skiljer sig åt efter namnområde kan du missta det ena för det andra och oavsiktligt skapa en implementering på stacken i stället för att använda hjälpfamiljen. Det kan vara svårt att diagnostisera i vissa fall, eftersom objektet kan förstöras medan utestående referenser fortfarande är under flygning. Ett påstående fångar nu upp detta för felsökningsbyggen. Även om påståendet inte identifierar stackallokering i en coroutine, är det ändå användbart för att fånga upp de flesta sådana felaktigheter.
Mer information finns i Diagnostisera direktallokeringar.
Förbättrade insamlingshjälpare och variadiska ombud
Den här uppdateringen åtgärdar begränsningen med insamlingshjälparna genom att även stödja projekterade typer. Detta kommer upp då och då med Windows Runtime-interop-API:er när de returnerar en projicerad typ.
Den här uppdateringen lägger också till stöd för get_strong och get_weak när du skapar en variadisk delegering (ej Windows Runtime).
Stöd för uppskjuten destruktion och säker QI under förstörelse
Det är inte ovanligt att i destruktorn för ett objekt av en körningsklass anropa en metod som tillfälligt ökar referensantalet. När referensantalet återgår till noll förstörs objektet en andra gång. I ett XAML-program kan du behöva utföra en QueryInterface (QI) i en destruktor för att anropa en rensningsimplementering uppåt eller nedåt i hierarkin. Men objektets referensantal har redan nått noll, så QI utgör också en återställning av referensräkningen.
Den här uppdateringen lägger till stöd för att stabilisera referensräkningen, vilket säkerställer att när den når noll, kan den aldrig återuppstå; medan du fortfarande kan QI:a för alla temporära föremål som du behöver under destruktionen. Den här proceduren är oundviklig i vissa XAML-program/kontroller, och C++/WinRT är nu motståndskraftig mot den.
Du kan skjuta upp destruktion genom att tillhandahålla en statisk final_release funktion för din implementeringstyp. Den sista återstående pekaren till objektet, i form av en std::unique_ptr, skickas till din final_release. Du kan sedan välja att flytta ägarskapet för den pekaren till någon annan kontext. Det är säkert för dig att använda QI på pekaren utan att utlösa en dubbeldestruktion. Men nettoändringen av referensantalet måste vara noll vid den punkt då du förstör objektet.
Returvärdet för final_release kan vara void, ett asynkront åtgärdsobjekt som IAsyncAction eller winrt::fire_and_forget.
struct Sample : implements<Sample, IStringable>
{
hstring ToString()
{
return L"Sample";
}
~Sample()
{
// Called when the unique_ptr below is reset.
}
static void final_release(std::unique_ptr<Sample> self) noexcept
{
// Move 'self' as needed to delay destruction.
}
};
I exemplet nedan anropas final_release när MainPage släpps (för sista gången). Den funktionen ägnar fem sekunder åt att vänta (i trådpoolen) och återupptas sedan med sidans Dispatcher (som kräver QI/AddRef/Release för att fungera). Sedan rensas en resurs i användargränssnittstråden. Och slutligen rensar det unique_ptr, vilket gör att destruktorn för MainPage- faktiskt anropas. Även i den här destruatorn anropas DataContext, vilket kräver en QI för IFrameworkElement.
Du behöver inte implementera din final_release som en coroutine. Men det fungerar, och det gör det mycket enkelt att flytta förstörelse till en annan tråd, vilket är vad som händer i det här exemplet.
struct MainPage : PageT<MainPage>
{
MainPage()
{
}
~MainPage()
{
DataContext(nullptr);
}
static IAsyncAction final_release(std::unique_ptr<MainPage> self)
{
co_await 5s;
co_await resume_foreground(self->Dispatcher());
co_await self->resource.CloseAsync();
// The object is destructed normally at the end of final_release,
// when the std::unique_ptr<MyClass> destructs. If you want to destruct
// the object earlier than that, then you can set *self* to `nullptr`.
self = nullptr;
}
};
Mer information finns i Uppskjuten destruktion.
Förbättrat stöd för arv av enkelgränssnitt i COM-format
Förutom för Windows Runtime-programmering används C++/WinRT också för att skapa och använda API:er med endast COM. Den här uppdateringen gör det möjligt att implementera en COM-server där det finns en gränssnittshierarki. Detta krävs inte för Windows Runtime. men det krävs för vissa COM-implementeringar.
Korrekt hantering av out parametrar
Det kan vara svårt att arbeta med out params, särskilt Windows Runtime-matriser. Med den här uppdateringen är C++/WinRT betydligt mer robust och motståndskraftig mot misstag när det gäller out parametrar och matriser; om dessa parametrar kommer via en språkprojektion eller från en COM-utvecklare som använder den råa ABI:en och som gör misstaget att inte initiera variabler konsekvent. I båda fallen gör C++/WinRT nu det rätta när det gäller att lämna ut planerade typer till ABI (genom att komma ihåg att frigöra resurser) och när det gäller att nollställa eller rensa ut parametrar som kommer över ABI.
Händelser hanterar nu ogiltiga tokener på ett tillförlitligt sätt
Implementeringen av winrt::event hanterar nu korrekt fallet där dess borttagningsmetod anropas med ett ogiltigt tokenvärde (ett värde som inte finns i matrisen).
Koroutinens lokala variabler förstörs nu innan koroutinen returnerar
Det traditionella sättet att implementera en koroutin kan göra det möjligt att förstöra lokala variabler i koroutinen efter att koroutinen returnerar/slutförs (i stället för före slutlig suspension). Återupptagandet av en servitör skjuts nu upp till den slutliga avstängningen, för att undvika det här problemet och för att ackumulera andra fördelar.
Nyheter och ändringar i Windows SDK version 10.0.17763.0 (Windows 10, version 1809)
Tabellen nedan innehåller nyheter och ändringar för C++/WinRT i Windows SDK version 10.0.17763.0 (Windows 10, version 1809).
| Ny eller ändrad funktion | Mer information |
|---|---|
| Brytande ändring. För att den ska kunna kompileras är C++/WinRT inte beroende av huvudfiler från Windows SDK. | Se Isolering från Windows SDK-huvudfiler, nedan. |
| Visual Studio-projektsystemformatet har ändrats. | Se Så här gör du om ditt C++/WinRT-projekt till en senare version av Windows SDK nedan. |
| Det finns nya funktioner och basklasser som hjälper dig att skicka ett samlingsobjekt till en Windows Runtime-funktion, eller för att implementera dina egna samlingsegenskaper och samlingstyper. | Se samlingar med C++/WinRT. |
| Du kan använda {Binding} markup-tillägg med dina C++/WinRT-körtidsklasser. | Mer information och kodexempel finns i Översikt över databindning. |
| Stöd för att avbryta en coroutine gör att du kan registrera ett återanrop för avbokning. | För mer information och kodexempel, se Avbryta en asynkron åtgärd samt annulleringsåteranrop. |
| När du skapar en delegering som pekar på en medlemsfunktion kan du upprätta en stark eller svag referens till det aktuella objektet (i stället för en rå this-pekare) vid den punkt där hanteraren registreras. | Mer information och kodexempel finns i Om du använder en medlemsfunktion som ombud underavsnittet i avsnittet Säker åtkomst till den här pekaren med ett ombud för händelsehantering. |
| Buggar har åtgärdats som upptäcktes av Visual Studio:s förbättrade överensstämmelse med C++-standarden. LLVM- och Clang-verktygskedjan används också bättre för att validera C++/WinRT:s standardefterlevnad. | Du stöter inte längre på problemet som beskrivs i Varför kompileras inte mitt nya projekt? Jag använder Visual Studio 2017 (version 15.8.0 eller senare) och SDK version 17134 |
Andra ändringar.
-
Brytande ändring.
winrt::get_abi(winrt::hstring const&) returnerar
void*istället förHSTRING. Du kan användastatic_cast<HSTRING>(get_abi(my_hstring));för att hämta en HSTRING. Se Interoperabilitet med ABI:s HSTRING. -
Brytande ändring.
winrt::put_abi(winrt::hstring&) returnerar
void**nu i stället förHSTRING*. Du kan användareinterpret_cast<HSTRING*>(put_abi(my_hstring));för att hämta en HSTRING*. Se Interoperabilitet med ABI:s HSTRING. -
Brytande ändring. HRESULT projiceras nu som winrt::hresult. Om du behöver en HRESULT (för att göra typkontroll eller för att stödja typ-egenskaper) kan du använda
static_casten winrt::hresult. Annars konverteras winrt::hresult till HRESULT, förutsatt att du inkluderarunknwn.hinnan du inkluderar några C++/WinRT-huvuden. -
Brytande ändring. GUID projiceras nu som winrt::guid. För API:er som du implementerar måste du använda winrt::guid för GUID-parametrar. Annars konverteras winrt::guid till GUID, så länge du inkluderar
unknwn.hinnan du inkluderar C++/WinRT-huvuden. Se Samverkan med ABI:s GUID-struktur. - Brytande ändring. Winrt::handle_type konstruktorn har hårdnat genom att göra den explicit (det är nu svårare att skriva felaktig kod med den). Om du behöver tilldela ett raw-referensvärde anropar du funktionen handle_type::attach i stället.
-
Brytande ändring. Signaturerna för WINRT_CanUnloadNow och WINRT_GetActivationFactory har ändrats. Du får inte deklarera dessa funktioner alls. Inkludera
winrt/base.hi stället (som inkluderas automatiskt om du inkluderar C++/WinRT Windows-namnområdeshuvudfiler) för att inkludera deklarationerna för dessa funktioner. - För winrt::clock struct är from_FILETIME/to_FILETIME inaktuella till förmån för from_file_time/to_file_time.
- Förenklade API:er som förväntar sig IBuffer-parametrar . De flesta API:er föredrar samlingar eller matriser. Men vi kände att vi borde göra det lättare att anropa API:er som förlitar sig på IBuffer. Den här uppdateringen ger direkt åtkomst till data bakom en IBuffer-implementering . Den använder samma namngivningskonvention för data som den som används av C++ Standard Library-containrarna. Den konventionen undviker också kollisioner med metadatanamn som konventionellt börjar med en versal bokstav.
- Förbättrad kodgenerering: olika förbättringar för att minska kodstorleken, förbättra inlining och optimera fabrikscachelagring.
- Onödig rekursion har tagits bort. När kommandoraden refererar till en mapp i stället för till en specifik
.winmdsökercppwinrt.exeverktyget inte längre rekursivt efter.winmdfiler. Verktygetcppwinrt.exehanterar nu även dubbletter på ett intelligentare sätt, vilket gör det mer motståndskraftigt mot användarfel och för dåligt formade.winmdfiler. - Förstärkta smarta pekare. Tidigare misslyckades händelserevokerare med att återkalla när de tilldelats ett nytt värde genom förflyttning. Detta hjälpte till att upptäcka ett problem där smarta pekarklasser inte hanterade självtilldelning på ett tillförlitligt sätt, med rötter i mallen winrt::com_ptr-strukt. winrt::com_ptr har åtgärdats och händelseåterkallare har korrigerats för att hantera flyttsemantik korrekt så att de återkallas vid tilldelning.
Viktigt!
Viktiga ändringar gjordes i C++/WinRT Visual Studio-tillägget (VSIX), både i version 1.0.181002.2 och senare i version 1.0.190128.4. Mer information om dessa ändringar och hur de påverkar dina befintliga projekt finns Visual Studio-stöd för C++/WinRT- och tidigare versioner av VSIX-tillägget.
Isolering från Windows SDK-huvudfiler
Detta kan vara en icke-bakåtkompatibel ändring för din kod.
För att kompilera är C++/WinRT inte längre beroende av huvudfiler från Windows SDK. Rubrikfiler i C-körningsbiblioteket (CRT) och C++ Standard Template Library (STL) innehåller inte heller några Windows SDK-huvuden. Och det förbättrar standardefterlevnad, undviker oavsiktliga beroenden och minskar avsevärt antalet makron som du måste skydda dig mot.
Detta oberoende innebär att C++/WinRT nu är mer portabelt och uppfyller standarder, och det ökar möjligheten att det blir ett korskompilator- och plattformsoberoende bibliotek. Det innebär också att C++/WinRT-huvudena inte påverkas negativt av makron.
Om du tidigare har lämnat den till C++/WinRT för att inkludera alla Windows-huvuden i projektet måste du nu inkludera dem själv. Det är i alla fall alltid bästa praxis att uttryckligen inkludera de rubriker som du är beroende av och inte lämna det till ett annat bibliotek för att inkludera dem åt dig.
För närvarande är de enda undantagen för Windows SDK-huvudfilisolering för inbyggda och numeriska objekt. Det finns inga kända problem med de senaste återstående beroendena.
I ditt projekt kan du återaktivera interop med Windows SDK-header om du behöver. Du kanske till exempel vill implementera ett COM-gränssnitt (rotat i IUnknown). Ta till exempel med unknwn.h innan du tar med C++/WinRT-huvuden. Detta gör att C++/WinRT-basbiblioteket aktiverar olika krokar för att stödja klassiska COM-gränssnitt. Ett kodexempel finns i Skapa COM-komponenter med C++/WinRT. På samma sätt inkluderar du uttryckligen alla andra Windows SDK-huvuden som deklarerar typer och/eller funktioner som du vill anropa.
Så här gör du om ditt C++/WinRT-projekt till en senare version av Windows SDK
Metoden för att rikta om projektet som sannolikt kommer att resultera i färre kompilator- och länkproblem är också den mest arbetsintensiva. Den metoden innebär att skapa ett nytt projekt (som riktar sig till valfri Windows SDK-version) och sedan kopierar filer till det nya projektet från ditt gamla. Det kommer att finnas delar av dina gamla filer .vcxproj och .vcxproj.filters som du kan kopiera över för att slippa lägga till filer i Visual Studio.
Det finns dock två andra sätt att göra om projektet i Visual Studio.
- Gå till projektegenskapen Allmän>Windows SDK-version och välj Alla konfigurationer och Alla plattformar. Ange Windows SDK-version till den version som du vill rikta in dig på.
- Högerklicka på projektnoden i Solution Explorer, klicka på Ommåla projekt, välj de versioner som du vill rikta in dig på och klicka sedan på OK.
Om du stöter på kompilator- eller länkfel när du har använt någon av dessa två metoder kan du försöka rensa lösningen (Skapa>ren lösning och/eller ta bort alla temporära mappar och filer manuellt) innan du försöker skapa den igen.
Om C++-kompilatorn genererar felet C2039: 'IUnknown': är inte medlem i ''global namespace''' lägger du till #include <unknwn.h> längst upp i pch.h filen (innan du tar med några C++/WinRT-huvuden).
Du kan också behöva lägga #include <hstring.h> till efter det.
Om C++-länkaren genererar "fel LNK2019: olöst extern symbol _WINRT_CanUnloadNow@0 som refereras i funktionen _VSDesignerCanUnloadNow@0", kan du lösa det genom att lägga till #define _VSDESIGNER_DONT_LOAD_AS_DLL i din pch.h-fil.