Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Naarmate volgende versies van C++/WinRT worden uitgebracht, wordt in dit onderwerp beschreven wat er nieuw is en wat er is gewijzigd.
Samenvouwen van recente verbeteringen/toevoegingen vanaf maart 2020
Tot 23% kortere buildtijden
De C++/WinRT- en C++-compilerteams hebben samengewerkt om alles te doen wat er mogelijk is om de buildtijden te verkorten. We hebben gekeken naar compileranalyse om erachter te komen hoe de interne kenmerken van C++/WinRT kunnen worden geherstructureerd om de C++-compiler te helpen de compilatietijd te elimineren en hoe de C++-compiler zelf kan worden verbeterd om de C++/WinRT-bibliotheek te verwerken. C++/WinRT is geoptimaliseerd voor de compiler; en de compiler is geoptimaliseerd voor C++/WinRT.
Laten we bijvoorbeeld het slechtste scenario nemen van het bouwen van een vooraf gecompileerde header (PCH) die elke C++/WinRT-projectienaamruimteheader bevat.
| Versie | PCH-grootte (bytes) | Tijd (s) |
|---|---|---|
| C++/WinRT vanaf juli, met Visual C++ 16.3 | 3,004,104,632 | 31 |
| versie 2.0.200316.3 van C++/WinRT, met Visual C++ 16.5 | 2,393,515,336 | 24 |
Een afname van 20% in grootte en een afname van 23% van de buildtijd.
Verbeterde MSBuild-ondersteuning
We hebben veel geïnvesteerd in het verbeteren van MSBuild-ondersteuning voor een grote selectie van verschillende scenario's.
Nog snellere caching in de fabriek
We hebben de inlining van de factory-cache verbeterd, zodat hot paths beter inline kunnen worden verwerkt, wat resulteert in een snellere uitvoering.
Deze verbetering heeft geen invloed op de codegrootte, zoals hieronder wordt beschreven in optimized EH-code-gen, als uw toepassing intensief gebruikmaakt van C++-uitzonderingsafhandeling, kunt u uw binaire bestand verkleinen met behulp van de /d2FH4 optie, die standaard is ingeschakeld in nieuwe projecten die zijn gemaakt met Visual Studio 2019 16.3 en hoger.
Efficiënter boksen
Bij gebruik in een XAML-toepassing is winrt::box_value nu efficiënter (zie Boksen en uitpakken). Toepassingen die veel boksen doen, merken ook een vermindering van de codegrootte.
Ondersteuning voor het implementeren van COM-interfaces die IInspectable implementeren
Als u een (niet-Windows-Runtime) COM-interface wilt implementeren die alleen IInspectable implementeert, kunt u dit nu doen met C++/WinRT. Zie COM-interfaces die IInspectable implementeren.
Verbeteringen voor modulevergrendeling
Controle over modulevergrendeling maakt het nu mogelijk om zowel aangepaste hostingscenario's als het vergrendelingen op moduleniveau helemaal te elimineren. Zie Verbeteringen voor modulevergrendeling.
Ondersteuning voor foutinformatie buiten Windows Runtime
Sommige API's (zelfs sommige Windows Runtime API's) melden fouten zonder Windows Runtime api's voor fout origination te gebruiken. In dergelijke gevallen valt C++/WinRT nu terug op het gebruik van COM-foutgegevens. Zie C++/WinRT-ondersteuning voor informatie over niet-WinRT-fouten.
C++-moduleondersteuning inschakelen
Ondersteuning voor C++-modules is terug, maar alleen in een experimentele vorm. De functie is nog niet voltooid in de C++-compiler.
Efficiëntere coroutinehervatting
C++/WinRT-coroutines presteren al goed, maar we blijven zoeken naar manieren om dat te verbeteren. Zie De schaalbaarheid van coroutine-hervatting verbeteren.
Nieuwe asynchrone when_all- en when_any-hulpfuncties
De when_all helperfunctie maakt een IAsyncAction-object dat wordt voltooid wanneer alle opgegeven wachtbare objecten zijn voltooid. De when_any helper maakt een IAsyncAction die wordt voltooid wanneer een van de opgegeven wachtbare bestanden is voltooid.
Zie when_any async-helper toevoegen en when_all async-helper toevoegen.
Andere optimalisaties en toevoegingen
Daarnaast zijn er veel bugfixes en kleine optimalisaties en toevoegingen geïntroduceerd, waaronder verschillende verbeteringen om foutopsporing te vereenvoudigen en interne en standaardimplementaties te optimaliseren. Volg deze koppeling voor een volledige lijst: https://github.com/microsoft/xlang/pulls?q=is%3Apr+is%3Aclosed.
Nieuws en wijzigingen in C++/WinRT 2.0
Voor meer informatie over C++/WinRT Visual Studio Extension (VSIX), de Microsoft.Windows. CppWinRT NuGet-pakket en het cppwinrt.exe hulpprogramma, inclusief hoe u deze kunt verkrijgen en installeren, raadpleegt u Visual Studio ondersteuning voor C++/WinRT, XAML, de VSIX-extensie en het NuGet-pakket.
Wijzigingen in de C++/WinRT-Visual Studio-extensie (VSIX) voor versie 2.0
- De foutopsporings visualiseren ondersteunt nu Visual Studio 2019; en blijft ondersteuning bieden voor Visual Studio 2017.
- Er zijn talloze oplossingen voor fouten aangebracht.
Wijzigingen in de Microsoft.Windows. CppWinRT NuGet-pakket voor versie 2.0
- Het
cppwinrt.exehulpprogramma is nu opgenomen in het NuGet-pakket Microsoft.Windows.CppWinRT en genereert op aanvraag platformprojectieheaderbestanden voor elk project. Daarom is hetcppwinrt.exehulpprogramma niet langer afhankelijk van de Windows SDK (hoewel het hulpprogramma nog steeds om compatibiliteitsredenen bij de SDK wordt geleverd). -
cppwinrt.exegenereert nu projectieheaders onder elke platform-/configuratiespecifieke tussenmap ($IntDir) om parallelle builds in te schakelen. - De C++/WinRT-buildondersteuning (props/targets) is nu volledig gedocumenteerd, voor het geval u uw projectbestanden handmatig wilt aanpassen. Zie de README van het Microsoft.Windows.CppWinRT NuGet-pakket.
- Er zijn talloze oplossingen voor fouten aangebracht.
Wijzigingen in C++/WinRT voor versie 2.0
Open source
Het cppwinrt.exe hulpprogramma maakt gebruik van een Windows Runtime metagegevensbestand (.winmd) en genereert er een standaard-C++-bibliotheek op basis van headers die de API's projecteert die in de metagegevens worden beschreven. Op die manier kunt u deze API's gebruiken vanuit uw C++/WinRT-code.
Dit hulpprogramma is nu een volledig open source project dat beschikbaar is op GitHub. Bezoek Microsoft/cppwinrt.
xlang-bibliotheken
Een volledig draagbare header-only-bibliotheek (voor het parseren van de ECMA-335-metagegevensindeling die door de Windows Runtime wordt gebruikt) vormt voortaan de basis voor alle Windows Runtime- en xlang-tools. Opmerkelijk is ook dat we het cppwinrt.exe-hulpprogramma met behulp van de xlang-bibliotheken vanaf de basis hebben herschreven. Dit biedt veel nauwkeurigere metagegevensquery's, waarmee enkele langdurige problemen met de C++/WinRT-taalprojectie worden opgelost.
Minder afhankelijkheden
Vanwege de xlang-metagegevenslezer heeft het cppwinrt.exe hulpprogramma zelf minder afhankelijkheden. Hierdoor is het veel flexibeler en bruikbaarder in meer scenario's, met name in beperkte buildomgevingen. Opvallend is dat het niet langer afhankelijk is van RoMetadata.dll.
Dit zijn de afhankelijkheden voor cppwinrt.exe 2.0.
- ADVAPI32.dll
- KERNEL32.dll
- SHLWAPI.dll
- XmlLite.dll
Al deze DLL's zijn niet alleen beschikbaar op Windows 10, maar helemaal tot Windows 7, en zelfs Windows Vista. Als u dat wilt, kan uw oude buildserver met Windows 7 nu cppwinrt.exe uitvoeren om C++-headers voor uw project te genereren. Met wat werk kunt u zelfs C++/WinRT uitvoeren op Windows 7, als dat interessant voor u is.
Vergelijk de bovenstaande lijst met deze afhankelijkheden, die cppwinrt.exe 1.0 heeft.
- 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
Het kenmerk Windows Runtime noexcept
De Windows Runtime heeft een nieuw [noexcept] kenmerk, dat u kunt gebruiken om uw methoden en eigenschappen in MIDL 3.0 te versieren. De aanwezigheid van het attribuut geeft ondersteunende hulpprogramma's aan dat uw implementatie geen uitzondering opwerpt en ook geen HRESULT retourneert die een fout aangeeft. Hierdoor kunnen taalprojecties het genereren van code optimaliseren door de overhead voor het afhandelen van uitzonderingen te voorkomen die nodig is om ABI-aanroepen (Application Binary Interface) te ondersteunen die mogelijk mislukken.
C++/WinRT maakt hiervan gebruik door C++ noexcept -implementaties te produceren van zowel de verbruikende als de creatiecode. Als u API-methoden of -eigenschappen hebt die niet kunnen mislukken en u zich zorgen maakt over de omvang van de code, kunt u dit kenmerk nader bekijken.
Geoptimaliseerde codegeneratie
C++/WinRT genereert nu nog efficiëntere C++-broncode (achter de schermen) zodat de C++-compiler de kleinste en meest efficiënte binaire code kan produceren. Veel van de verbeteringen zijn gericht op het verlagen van de kosten van de afhandeling van uitzonderingen door onnodige unwind-informatie te vermijden. Binaire bestanden die grote hoeveelheden C++/WinRT-code gebruiken, zien ongeveer een 4% vermindering van de codegrootte. De code is ook efficiënter (deze wordt sneller uitgevoerd) vanwege het verminderde aantal instructies.
Deze verbeteringen zijn ook afhankelijk van een nieuwe functie voor interoperabiliteit die voor u beschikbaar is. Alle C++/WinRT-typen die resource-eigenaren zijn, bevatten nu een constructor voor het rechtstreeks overnemen van eigendom, waardoor de vorige tweestapsbenadering wordt vermeden.
ABI::Windows::Foundation::IStringable* raw = ...
IStringable projected(raw, take_ownership_from_abi);
printf("%ls\n", projected.ToString().c_str());
Geoptimaliseerde codegeneratie voor uitzonderingsafhandeling (EH)
Deze wijziging vormt een aanvulling op het werk dat is uitgevoerd door het Microsoft C++-optimalisatieteam om de kosten van uitzonderingsafhandeling te verlagen. Als u binaire interfaces (ABI's) (zoals COM) gebruikt in uw code, ziet u veel code volgens dit patroon.
int32_t Function() noexcept
{
try
{
// code here constitutes unique value.
}
catch (...)
{
// code here is always duplicated.
}
}
Met C++/WinRT zelf wordt dit patroon gegenereerd voor elke API die wordt geïmplementeerd. Met duizenden API-functies kan elke optimalisatie hier aanzienlijk zijn. In het verleden zou de optimizer niet detecteren dat deze catch-blokken allemaal identiek zijn, dus het dupliceert veel code rond elke ABI (wat op zijn beurt heeft bijgedragen aan de overtuiging dat het gebruik van uitzonderingen in systeemcode grote binaire bestanden produceert). Vanaf Visual Studio 2019 voegt de C++-compiler echter al deze catch-funclets samen en slaat alleen de unieke exemplaren op. Het resultaat is een verdere en algehele 18% vermindering van de codegrootte voor binaire bestanden die sterk afhankelijk zijn van dit patroon. Eh-code is nu niet alleen efficiënter dan het gebruik van retourcodes, maar ook de zorg over grotere binaire bestanden is nu iets van het verleden.
Incrementele buildverbeteringen
Het cppwinrt.exe hulpprogramma vergelijkt nu de uitvoer van een gegenereerd header-/bronbestand met de inhoud van een bestaand bestand op schijf en schrijft alleen het bestand uit als het bestand daadwerkelijk is gewijzigd. Dit bespaart veel tijd met schijf-I/O en zorgt ervoor dat de bestanden niet als 'vuil' worden beschouwd door de C++-compiler. Het resultaat is dat hercompilatie in veel gevallen wordt vermeden of verminderd.
Algemene interfaces worden nu allemaal gegenereerd
Vanwege de xlang-metagegevenslezer genereert C++/WinRT nu alle geparameteriseerde of algemene interfaces van metagegevens. Interfaces zoals Windows::Foundation::Collections::IVector<T> worden nu gegenereerd op basis van metagegevens in plaats van met de hand geschreven in winrt/base.h. Het resultaat is dat de grootte van winrt/base.h de helft is gesneden en dat optimalisaties rechtstreeks in de code worden gegenereerd (wat lastig was om te doen met de handgerolde benadering).
Belangrijk
Interfaces zoals het voorbeeld dat nu wordt gegeven, worden weergegeven in hun respectieve naamruimteheaders, in plaats van in winrt/base.h. Dus als u dit nog niet hebt gedaan, moet u de juiste naamruimteheader opnemen om de interface te kunnen gebruiken.
Optimalisaties van onderdelen
Deze update voegt ondersteuning toe voor verschillende extra opt-in-optimalisaties voor C++/WinRT, zoals beschreven in de onderstaande secties. Omdat deze optimalisaties belangrijke wijzigingen veroorzaken (die u mogelijk kleine wijzigingen moet aanbrengen ter ondersteuning), moet u deze expliciet inschakelen. Stel in Visual Studio de projecteigenschap Common Properties>C++/WinRT>Optimized in op Ja. Dat heeft het effect van het toevoegen <CppWinRTOptimized>true</CppWinRTOptimized> aan uw projectbestand. En het heeft hetzelfde effect als het toevoegen van de optie -opt[imize] bij het aanroepen van cppwinrt.exe via de opdrachtregel.
Een nieuw project (op basis van een projectsjabloon) zal standaard -opt gebruiken.
Uniforme bouw en directe implementatietoegang
Met deze twee optimalisaties heeft uw onderdeel directe toegang tot zijn eigen implementatietypen, zelfs wanneer het alleen de verwachte typen gebruikt. U hoeft geen make-, make_self- of get_self te gebruiken als u gewoon het openbare API-oppervlak wilt gebruiken. Uw aanroepen worden gecompileerd tot rechtstreekse aanroepen naar de implementatie, en die kunnen zelfs volledig worden geïnlineerd.
Zie Aanmelden voor uniforme constructie en directe implementatietoegang voor meer informatie en codevoorbeelden.
Type-uitgewiste factories
Deze optimalisatie vermijdt de #include afhankelijkheden, module.g.cpp zodat deze niet telkens opnieuw hoeven te worden gecompileerd wanneer er één implementatieklasse verandert. Dit resulteert in betere buildprestaties.
Slimmer en efficiënter module.g.cpp voor grote projecten met meerdere bibliotheken
Het module.g.cpp-bestand bevat nu ook twee extra composable helpers, genaamd winrt_can_unload_now en winrt_get_activation_factory. Deze zijn ontworpen voor grotere projecten waarbij een DLL bestaat uit een aantal bibliotheken, elk met eigen runtimeklassen. In dat geval moet u de DllGetActivationFactory en DllCanUnloadNow van de DLL handmatig aan elkaar koppelen. Deze helpers maken het voor u veel gemakkelijker om dat te doen, door fouten met onjuiste oorsprong te voorkomen. De vlag -lib van het hulpprogramma cppwinrt.exe kan ook worden gebruikt om elke afzonderlijke lib een eigen preambule te geven (in plaats van winrt_xxx), zodat de functies van elke lib afzonderlijk kunnen worden benoemd en daardoor ondubbelzinnig kunnen worden gecombineerd.
Ondersteuning voor Coroutine
Coroutine-ondersteuning wordt automatisch opgenomen. Voorheen bevond de ondersteuning zich op meerdere plaatsen, wat we voelden te beperken. En dan was er tijdelijk een winrt/coroutine.h headerbestand nodig voor v2.0, maar dat is niet meer nodig. Omdat de Windows Runtime asynchrone interfaces nu worden gegenereerd, in plaats van met de hand geschreven, bevinden ze zich nu in winrt/Windows.Foundation.h. Afgezien van het feit dat dit beter onderhoudbaar en beter te ondersteunen is, betekent het dat coroutine-helpers zoals resume_foreground niet langer aan het einde van de header van een specifieke naamruimte hoeven te worden toegevoegd. In plaats daarvan kunnen ze hun afhankelijkheden natuurlijker opnemen. Hierdoor kunnen resume_foreground niet alleen ondersteuning bieden voor het hervatten van een bepaalde Windows::UI::Core::CoreDispatcher, maar het kan nu ook ondersteuning bieden voor hervatting van een bepaalde Windows::System::D ispatcherQueue. Eerder kon er slechts één worden ondersteund; maar niet beide, omdat de definitie zich slechts in één naamruimte kan bevinden.
Hier volgt een voorbeeld van de ondersteuning voor DispatcherQueue .
...
#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);
}
De coroutine helpers zijn nu ook ingericht met [[nodiscard]], waardoor hun bruikbaarheid wordt verbeterd. Als u vergeet ze te co_await (of niet beseft dat dat moet) om ze te laten werken, leiden dergelijke fouten nu door [[nodiscard]] tot een waarschuwing van de compiler.
Hulp bij het diagnosticeren van directe (stack)-toewijzingen
Omdat de geprojecteerde en implementatieklassennamen (standaard) hetzelfde zijn en alleen door de naamruimte van elkaar verschillen, is het mogelijk de ene met de andere te verwarren en per ongeluk een implementatie op de stack aan te maken, in plaats van de make-helperfuncties te gebruiken. Dit kan in sommige gevallen moeilijk vast te stellen zijn, omdat het object kan worden vernietigd terwijl uitstaande referenties nog in omloop zijn. Een assert signaleert dit nu in debug-builds. Hoewel de assertie geen stacktoewijzing in een coroutine detecteert, is het toch handig om de meeste dergelijke fouten te ondervangen.
Zie Diagnose van directe toewijzingen voor meer informatie.
Verbeterde hulpfuncties voor vastleggen en variadische delegaten
Met deze update wordt de beperking opgelost met de capture-helpers door ook projecttypen te ondersteunen. Dit komt nu en dan met de Windows Runtime interop-API's, wanneer ze een geprojecteerd type retourneren.
Deze update voegt ook ondersteuning toe voor get_strong en get_weak bij het maken van een variadische delegate (geen Windows Runtime).
Ondersteuning voor uitgestelde vernietiging en veilige QI tijdens vernietiging
Het is niet ongebruikelijk om in de destructor van een runtimeklasseobject een methode aan te roepen die de referentietelling tijdelijk verhoogt. Wanneer de referentietelling weer op nul komt, wordt het object een tweede keer vernietigd. In een XAML-toepassing moet u mogelijk een QueryInterface (QI) uitvoeren in een destructor om een opschoningsimplementatie omhoog of omlaag in de hiërarchie aan te roepen. Maar de referentietelling van het object is al op nul gekomen, dus die QI vormt ook een sprong in de referentietelling.
Deze update voegt ondersteuning toe voor debouncing van de referentietelling, zodat deze, zodra die nul bereikt, niet meer opnieuw kan worden verhoogd, terwijl u nog steeds QI kunt uitvoeren voor alle tijdelijke objecten die u tijdens de vernietiging nodig hebt. Deze procedure is onvermijdelijk in bepaalde XAML-toepassingen/besturingselementen en C++/WinRT is nu tolerant voor deze procedure.
U kunt vernietiging uitstellen door een statische final_release functie op te geven voor uw implementatietype. De laatste resterende aanwijzer naar het object, in de vorm van een std::unique_ptr, wordt doorgegeven aan uw final_release. U kunt er vervolgens voor kiezen om het eigendom van die aanwijzer naar een andere context te verplaatsen. Je kunt veilig een QI op de pointer uitvoeren zonder een dubbele vernietiging te veroorzaken. Maar de nettowijziging in het aantal verwijzingen moet nul zijn op het punt dat u het object destructeert.
De retourwaarde van final_release kan een asynchroon bewerkingsobject zijn void, zoals IAsyncAction of 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.
}
};
In het volgende voorbeeld wordt final_release aangeroepen zodra de MainPage wordt vrijgegeven (voor de laatste keer). Die functie wacht vijf seconden (in de threadpool) en wordt vervolgens hervat via de Dispatcher van de pagina (waarvoor QI/AddRef/Release nodig zijn). Vervolgens wordt een resource op die UI-thread opgeschoond. En ten slotte wordt de unique_ptr gewist, waardoor de MainPage-destructor daadwerkelijk wordt aangeroepen. Zelfs in die destructor wordt DataContext aangeroepen, waarvoor een QI voor IFrameworkElement vereist is.
U hoeft uw final_release niet als coroutine te implementeren. Maar dat werkt wel, en het maakt het heel eenvoudig om vernietiging naar een andere thread te verplaatsen, wat in dit voorbeeld gebeurt.
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;
}
};
Zie Uitgestelde vernietiging voor meer informatie.
Verbeterde ondersteuning voor overname van één interface in COM-stijl
Naast Windows Runtime programmeren, wordt C++/WinRT ook gebruikt om COM-api's te maken en te gebruiken. Met deze update kunt u een COM-server implementeren waar zich een interfacehiërarchie bevindt. Dit is niet vereist voor de Windows Runtime; maar is vereist voor sommige COM-implementaties.
Juiste verwerking van out params
Het kan lastig zijn om met out parameters te werken, met name Windows Runtime matrices. Met deze update is C++/WinRT aanzienlijk robuuster en toleranter voor fouten als het gaat om out params en matrices, ongeacht of deze parameters binnenkomen via een taalprojectie, of van een COM-ontwikkelaar die de onbewerkte ABI gebruikt en die de fout maakt om variabelen niet consistent te initialiseren. In beide gevallen handelt C++/WinRT nu correct als het gaat om het doorgeven van geprojecteerde typen aan de ABI (door eraan te denken eventuele resources vrij te geven) en om het op nul zetten of wissen van parameters die via de ABI binnenkomen.
Gebeurtenissen verwerken nu op betrouwbare wijze ongeldige tokens
De winrt::event-implementatie verwerkt nu probleemloos het geval waarin de verwijdermethode wordt aangeroepen met een ongeldige tokenwaarde (een waarde die niet aanwezig is in de matrix).
Lokale Coroutine-variabelen worden nu vernietigd voordat de coroutine retourneert
De traditionele manier om een coroutine-type te implementeren kan ertoe leiden dat lokale variabelen binnen de coroutine nadat de coroutine terugkeert/wordt voltooid worden vernietigd (in plaats van vóór de laatste opschorting). De hervatting van een ober wordt nu uitgesteld tot de definitieve schorsing, om dit probleem te voorkomen en andere voordelen te krijgen.
Nieuws en wijzigingen in Windows SDK-versie 10.0.17763.0 (Windows 10, versie 1809)
De onderstaande tabel bevat nieuws en wijzigingen voor C++/WinRT in de Windows SDK-versie 10.0.17763.0 (Windows 10 versie 1809).
| Nieuwe of gewijzigde functie | Meer informatie |
|---|---|
| Incompatibele wijziging. Voor het compileren is C++/WinRT niet afhankelijk van headers van de Windows SDK. | Zie Isolatie van Windows SDK-headerbestanden hieronder. |
| De Visual Studio projectsysteemindeling is gewijzigd. | Zie Hoe u uw C++/WinRT-project opnieuw kunt instellen op een latere versie van de Windows SDK, hieronder. |
| Er zijn nieuwe functies en basisklassen waarmee u een verzamelingsobject kunt doorgeven aan een Windows Runtime functie of om uw eigen verzamelingseigenschappen en verzamelingstypen te implementeren. | Zie Verzamelingen met C++/WinRT. |
| U kunt de markeringsextensie {Binding} gebruiken met uw C++/WinRT-runtimeklassen. | Zie het overzicht van gegevensbindingen voor meer informatie en codevoorbeelden. |
| Met ondersteuning voor het annuleren van een coroutine kunt u een annuleringsaanroep registreren. | Zie Een asynchrone bewerking annuleren en annuleringscallbacks voor meer informatie en codevoorbeelden. |
| Wanneer u een delegate maakt die verwijst naar een memberfunctie, kunt u een sterke of zwakke verwijzing naar het huidige object tot stand brengen (in plaats van een ruwe this-pointer) op het moment dat de handler wordt geregistreerd. | Zie de subsectie Als u een memberfunctie als delegate gebruikt in de sectie Veilig toegang krijgen tot de aanwijzer this met een delegate voor gebeurtenisafhandeling voor meer informatie en codevoorbeelden. |
| Bugs zijn opgelost die zijn ontdekt door de verbeterde conformiteit van Visual Studio aan de C++-standaard. De LLVM- en Clang-hulpprogrammaketen wordt ook beter gebruikt om de standaarden van C++/WinRT te valideren. | U zult het probleem dat wordt beschreven in Waarom compileert mijn nieuwe project niet? Ik gebruik Visual Studio 2017 (versie 15.8.0 of hoger) en SDK-versie 17134 niet langer tegenkomen |
Andere wijzigingen.
-
Ingrijpende wijziging.
winrt::get_abi(winrt::hstring const&) retourneert
void*nu in plaats vanHSTRING. U kuntstatic_cast<HSTRING>(get_abi(my_hstring));gebruiken om een HSTRING op te halen. Zie Samenwerken met de HSTRING van de ABI. -
Incompatibele wijziging.
winrt::put_abi(winrt::hstring&) geeft nu
void**terug in plaats vanHSTRING*. U kuntreinterpret_cast<HSTRING*>(put_abi(my_hstring));gebruiken om een HSTRING* op te halen. Zie Samenwerken met de HSTRING van de ABI. -
Ingrijpende wijziging. HRESULT wordt nu geprojecteerd als winrt::hresult. Als u een HRESULT nodig hebt (om typecontrole uit te voeren of typeeigenschappen te ondersteunen), kunt u met
static_casteen winrt::hresult gebruiken. Anders wordt winrt::hresult geconverteerd naar HRESULT, zolang uunknwn.hopneemt voordat u C++/WinRT-headers opneemt. -
Incompatibele wijziging. GUID wordt nu geprojecteerd als winrt::guid. Voor API's die u implementeert, moet u winrt::guid gebruiken voor GUID-parameters. Anders wordt winrt::guid omgezet in GUID, zolang u
unknwn.hopneemt voordat u C++/WinRT-headers opneemt. Zie Samenwerken met de GUID-struct van de ABI. - Incompatibele wijziging. De winrt::handle_type constructor is beveiligd door deze expliciet te maken (het is nu moeilijker om onjuiste code mee te schrijven). Als u een onbewerkte ingangswaarde wilt toewijzen, roept u in plaats daarvan de functie handle_type::attach aan.
-
Incompatibele wijziging. De handtekeningen van WINRT_CanUnloadNow en WINRT_GetActivationFactory zijn gewijzigd. U moet deze functies helemaal niet declareren. Neem in plaats daarvan
winrt/base.hop (dat automatisch wordt opgenomen als u Windows-naamruimteheaderbestanden van C++/WinRT opneemt), zodat de declaraties van deze functies worden opgenomen. - Voor de winrt::clock-struct worden from_FILETIME/to_FILETIME afgeschaft ten gunste van from_file_time/to_file_time.
- Vereenvoudigde API's die IBuffer-parameters verwachten. De meeste API's geven de voorkeur aan verzamelingen of matrices. Maar we vonden dat we het gemakkelijker zouden maken OM API's aan te roepen die afhankelijk zijn van IBuffer. Deze update biedt directe toegang tot de gegevens achter een IBuffer-implementatie . Deze maakt gebruik van dezelfde naamconventie voor gegevens als de naamconventie die wordt gebruikt door de C++ Standard Library-containers. Deze conventie voorkomt ook conflicten met metagegevensnamen die conventioneel beginnen met een hoofdletter.
- Verbeterde codegeneratie: verschillende verbeteringen om de codegrootte te verminderen, de inlining te verbeteren en de fabriekscache te optimaliseren.
- Onnodige recursie verwijderd. Wanneer de opdrachtregel verwijst naar een map, in plaats van naar een specifieke
.winmd, zoekt hetcppwinrt.exehulpprogramma niet meer recursief naar.winmdbestanden. Hetcppwinrt.exehulpprogramma verwerkt nu ook duplicaten intelligenter, waardoor het toleranter is voor gebruikersfouten en voor slecht gevormde.winmdbestanden. - Verharde slimme aanwijzers. Voorheen slaagden de eventherroepers er niet in te herroepen wanneer via move-assignment een nieuwe waarde werd toegewezen. Dit heeft geholpen bij het ontdekken van een probleem waarbij slimme aanwijzerklassen niet betrouwbaar zelftoewijzing afhandelen; geroot in de winrt::com_ptr structsjabloon. winrt::com_ptr is gecorrigeerd en de event-revokers zijn hersteld om move-semantiek correct af te handelen, zodat gebeurtenissen bij toewijzing worden ingetrokken.
Belangrijk
Belangrijke wijzigingen zijn aangebracht in de extensie C++/WinRT-Visual Studio (VSIX), zowel in versie 1.0.181002.2 als hoger in versie 1.0.190128.4. Voor meer informatie over deze wijzigingen en hoe deze van invloed zijn op uw bestaande projecten, Visual Studio ondersteuning voor C++/WinRT en eerdere versies van de VSIX-extensie.
Isolatie van Windows SDK-headerbestanden
Dit is mogelijk een belangrijke wijziging voor uw code.
Voor het compileren is C++/WinRT niet langer afhankelijk van headerbestanden van de Windows SDK. Headerbestanden in de C-runtimebibliotheek (CRT) en de C++ Standard Template Library (STL) bevatten ook geen Windows SDK-headers. En dat verbetert de naleving van standaarden, voorkomt onbedoelde afhankelijkheden en vermindert het aantal macro's dat u moet beschermen.
Deze onafhankelijkheid betekent dat C++/WinRT nu meer draagbaar en standaarden compatibel is en dat het de mogelijkheid vergroot om een cross-compiler en platformoverschrijdende bibliotheek te worden. Dit betekent ook dat de C++/WinRT-headers geen negatieve gevolgen hebben voor macro's.
Als u het eerder aan C++/WinRT hebt overgelaten om eventuele Windows headers in uw project op te nemen, moet u deze nu zelf opnemen. Het is in ieder geval altijd raadzaam om de headers waarvan u afhankelijk bent expliciet op te nemen, in plaats van het aan een andere bibliotheek over te laten om die voor u op te nemen.
Momenteel zijn de enige uitzonderingen op Windows SDK-headerbestandisolatie voor intrinsieke kenmerken en numerieke gegevens. Er zijn geen bekende problemen met deze laatste resterende afhankelijkheden.
In uw project kunt u de interop opnieuw inschakelen met de Windows SDK-headers als dat nodig is. U kunt bijvoorbeeld een COM-interface implementeren (geroot in IUnknown). Voor dat voorbeeld neemt u unknwn.h op voordat u C++/WinRT-headers opneemt. Hierdoor zorgt u ervoor dat de C++/WinRT-basisbibliotheek verschillende hooks in staat stelt om klassieke COM-interfaces te ondersteunen. Zie Com-onderdelen maken met C++/WinRT voor een codevoorbeeld. Neem ook expliciet andere Windows SDK-headers op die typen en/of functies declareren die u wilt aanroepen.
Uw C++/WinRT-project opnieuw instellen op een latere versie van de Windows SDK
De methode om uw project opnieuw te retargeten die waarschijnlijk tot de minste compiler- en linkerproblemen leidt, is ook het meest arbeidsintensief. Deze methode omvat het maken van een nieuw project (gericht op de Windows SDK-versie van uw keuze) en het vervolgens kopiëren van bestanden naar uw nieuwe project van uw oude. Er zullen delen van uw oude .vcxproj- en .vcxproj.filters-bestanden zijn die u gewoon kunt kopiëren, zodat u geen bestanden meer hoeft toe te voegen in Visual Studio.
Er zijn echter twee andere manieren om uw project in Visual Studio te hertargeten.
- Ga naar de projecteigenschap Algemeen>Windows SDK-versie en selecteer Alle configuraties en alle platforms. Stel Windows SDK-versie in op de versie waarop u zich wilt richten.
- Klik in Solution Explorer met de rechtermuisknop op het projectknooppunt, klik op Retarget Projects, kies de versie(s) die u wilt targeten en klik vervolgens op OK.
Als er compiler- of linkerfouten optreden nadat u een van deze twee methoden hebt gebruikt, kunt u proberen de oplossing op te schonen (Build>Clean Solution en/of alle tijdelijke mappen en bestanden handmatig verwijderen) voordat u opnieuw probeert te bouwen.
Als de C++-compiler de melding 'fout C2039: 'IUnknown': is geen lid van ''global namespace''' geeft, voeg dan #include <unknwn.h> toe bovenaan in uw pch.h-bestand (voordat u C++/WinRT-headers includeert).
Mogelijk moet u hierna ook toevoegen #include <hstring.h> .
Als de C++-linker 'fout LNK2019: niet-opgelost extern symbool _WINRT_CanUnloadNow@0 waarnaar wordt verwezen in functie _VSDesignerCanUnloadNow@0' produceert, kunt u dit oplossen door dit toe te voegen #define _VSDESIGNER_DONT_LOAD_AS_DLL aan uw pch.h bestand.
Windows developer