Kommentar
Å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 storleksminskning på 20% och en 23% minskning av byggtiden.
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 cachelagring i fabriken
Vi har förbättrat inlining av fabrikscachen för att bättre infogade heta sökvägar, vilket leder till snabbare körning.
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 ett XAML-program är winrt::box_value nu effektivare (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 möjliggör 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 felinformation som inte är Windows-Runtime
Vissa API:er (även vissa Windows Runtime-API:er) rapporterar fel utan att använda API:er för felursprung i Windows Runtime. 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 when_all och when_any asynkrona hjälpverktyg
Hjälpfunktionen when_all skapar ett IAsyncAction-objekt som slutförs när alla angivna awaitables har slutförts. when_any-hjälpfunktionen skapar en IAsyncAction som slutförs när något av de angivna awaitables har slutförts.
Se hjälpfunktionen when_any för asynkronitet och hjälpfunktionen when_all för asynkronitet.
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 Extension (VSIX), NuGet-paketet Microsoft.Windows.CppWinRT 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ägg (VSIX) för version 2.0
- Felsökningsvisualiseraren stöder nu Visual Studio 2019, samt fortsätter att stödja Visual Studio 2017.
- Många felkorrigeringar har gjorts.
Ändringar i Microsoft.Windows. CppWinRT NuGet-paket för version 2.0
- Verktyget
cppwinrt.exeingår nu i Microsoft.Windows. CppWinRT NuGet-paketet och verktyget genererar platfomprojektionshuvuden för varje projekt på begäran. Verktyget är därförcppwinrt.exeinte längre beroende av Windows SDK (även om verktyget fortfarande levereras med SDK:n av kompatibilitetsskäl). -
cppwinrt.exegenererar nu projektionsheaderfiler under varje plattforms- och konfigurationsspecifik mellanliggande katalog ($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 Microsoft.Windows. CppWinRT NuGet-paket 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 projicerar 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 open-source projekt 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 xlangverktyg 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 den gamla byggservern som kör Windows 7 nu köras cppwinrt.exe för att generera C++-huvuden för projektet. 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
Attributet för Windows Runtime 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 syftar till att minska kostnaden för undantagshantering genom att undvika onödig unwind-information. 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 det 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 i och med Visual Studio 2019 slår C++-kompilatorn ihop alla dessa catch-funclets och lagrar bara de 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 inkrementell kompilering
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 storleken på winrt/base.h har halverats och att optimeringar genereras direkt i koden (vilket var svårt att göra med den specialskrivna lösningen).
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 innebär brytande ändringar (vilket kan innebära att du behöver göra mindre ändringar för att stödja dem) måste du aktivera dem uttryckligen. I Visual Studio anger du projektegenskapen Gemensamma egenskaper>C++/WinRT>Optimerad till Ja. Det innebär att du lägger <CppWinRTOptimized>true</CppWinRTOptimized> till 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 som standard att använda -opt.
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 make, make_self eller get_self om du bara vill använda den offentliga API-ytan. Dina anrop kompileras ned till direkta anrop till implementeringen, och de kan till och med vara helt inlindade.
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:ernas 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 flagga cppwinrt.exe-lib kan också användas för att ge varje enskilt lib sitt eget preamble (snarare än winrt_xxx), så att varje libs 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 Windows Runtime asynkrona 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::D ispatcherQueue. 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);
}
Coroutine-hjälparna är nu också dekorerade med [[nodiscard]], vilket förbättrar deras användbarhet. Om du glömmer att (eller inte inser att du måste) co_await dem för att de ska fungera, ger sådana misstag nu, på grund av [[nodiscard]], upphov till en kompilatorvarning.
Hjälp med att diagnostisera direkta allokeringar (stacken)
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. En assertsats fångar nu upp detta i debugversioner. Även om assert-satsen inte upptäcker stackallokering inuti en korutin, är den ändå användbar för att fånga upp de flesta sådana misstag.
Mer information finns i Diagnostisera direktallokeringar.
Förbättrade insamlingshjälpare och variadiska ombud
Den här uppdateringen åtgärdar begränsningen hos capture-hjälpfunktionerna genom att även stödja projicerade 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 vid skapande av en delegat med variabelt antal argument (som inte är en Windows Runtime-delegat).
Stöd för uppskjuten destruktion och säker QI under förstörelse
Det är inte ovanligt att man i destruktorn för ett objekt av en runtimeklass anropar en metod som tillfälligt höjer 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 innebär också en studs i referensräkningen.
Den här uppdateringen lägger till stöd för att hantera studsar i referensräkningen, vilket säkerställer att den, när den väl har nått noll, aldrig kan återupplivas, samtidigt som du fortfarande kan använda QI för alla temporära objekt som behövs 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. Du kan tryggt QI pekaren utan att orsaka att objektet förstörs två gånger. 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 MainPage-destructor faktiskt anropas. Även i den destruatorn anropas DataContext , vilket kräver en QI för IFrameworkElement.
Du behöver inte implementera dina 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 params
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 paramer och matriser, oavsett om dessa parametrar kommer via en språkprojektion eller från en COM-utvecklare som använder den råa ABI:en och vem 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 token tillförlitligt
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).
Korutinens lokala variabler förstörs nu innan korutinen returnerar
Det traditionella sättet att implementera en koroutintyp kan innebära att lokala variabler inom koroutinen förstörs efter att koroutinen returnerar/slutförs (i stället för före den slutliga suspenderingen). Å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 |
|---|---|
| Icke-bakåtkompatibel ändring. För att kunna kompileras behöver C++/WinRT inte headerfiler från Windows SDK. | Se Isolering från Windows SDK-huvudfilerna nedan. |
| Det 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 markeringstillägget {Binding} med dina C++/WinRT-körningsklasser. | Mer information och kodexempel finns i Översikt över databindning. |
| Med stöd för att avbryta en coroutine kan du registrera ett återanrop om annullering. | Mer information och kodexempel finns i Avbryta en asynkron åtgärd och återanrop för annullering. |
| När du skapar en delegat som pekar på en medlemsfunktion kan du skapa en stark eller svag referens till det aktuella objektet (i stället för en rå this-pekare) när hanteraren registreras. | Mer information och kodexempel finns i avsnittet Om du använder en medlemsfunktion som ombud i avsnittet Säker åtkomst till den här pekaren med ett ombud för händelsehantering. |
| Fel har åtgärdats som upptäcktes tack vare Visual Studios förbättrade efterlevnad av 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.
-
Icke-bakåtkompatibel ändring.
winrt::get_abi(winrt::hstring const&) returnerar nu
void*i stället förHSTRING. Du kan användastatic_cast<HSTRING>(get_abi(my_hstring));för att hämta en HSTRING. Se Samverkan med ABI:s HSTRING. -
Icke-bakåtkompatibel ändring.
winrt::put_abi(winrt::hstring&) returnerar nu
void**i stället förHSTRING*. Du kan användareinterpret_cast<HSTRING*>(put_abi(my_hstring));för att få en HSTRING*. Se Samverkan med ABI:s HSTRING. -
Icke-bakåtkompatibel ändring. HRESULT beräknas nu som winrt::hresult. Om du behöver en HRESULT (för att göra typkontroll eller för att stödja typegenskaper) kan du
static_casten winrt::hresult. Annars konverteras winrt::hresult till HRESULT, så länge du inkluderarunknwn.hinnan du inkluderar några C++/WinRT-rubrikfiler. -
Icke-bakåtkompatibel ä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-struct. - Icke-bakåtkompatibel ä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.
-
Icke-bakåtkompatibel ä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 inlinning 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 lyckades händelseåterkallarna inte återkalla vid flyttilldelning av ett nytt värde. Detta hjälpte till att avslöja ett problem där smart pointer-klasser inte hanterade självtilldelning på ett tillförlitligt sätt, vilket hade sin grund i strukturmallen winrt::com_ptr. winrt::com_ptr har rättats, och händelseåterkallarna har rättats för att hantera flyttsemantik korrekt så att de återkallar vid tilldelning.
Viktigt!
Viktiga ändringar gjordes i VSIX (C++/WinRT Visual Studio Extension), 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 i Visual Studio-stöd för C++/WinRT och tidigare versioner av VSIX-tillägget.
Isolering från Windows SDK-huvudfiler
Detta kan innebära en ändring som bryter bakåtkompatibiliteten för din kod.
För att kompilera beror C++/WinRT inte längre på 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 överlät åt C++/WinRT att inkludera eventuella headerfiler för Windows 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 interoperabilitet med headerfilerna i Windows SDK om du behöver det. 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 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 ändra målplattform för projektet, som sannolikt leder till minst antal problem med kompilatorn och länkaren, är också den mest arbetskrävande. Den metoden innebär att skapa ett nytt projekt (som riktar sig till den Windows SDK-version som du väljer) och sedan kopierar filer till ditt nya projekt från ditt gamla. Det finns delar av dina gamla .vcxproj- och .vcxproj.filters-filer som du bara kan kopiera, så att du slipper lägga till filer i Visual Studio.
Det finns dock två andra sätt att ändra målversion för projektet i Visual Studio.
- Gå till projektegenskapen Allmänt>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å.
- I Prieskumník riešení högerklickar du på projektnoden, klickar på Ommåla projekt, väljer de versioner som du vill rikta in dig på och klickar 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 refererad till i funktionen _VSDesignerCanUnloadNow@0" kan du lösa det genom att lägga till #define _VSDESIGNER_DONT_LOAD_AS_DLL i filen pch.h.
Windows developer