Delen via


Wat is er nieuw in C++/WinRT

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 bouwtijden

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 in grootte van 20% en een vermindering van 23% in bouwtijd.

Verbeterde MSBuild-ondersteuning

We hebben veel geïnvesteerd in het verbeteren van MSBuild ondersteuning voor een grote selectie van verschillende scenario's.

Nog snellere fabriekscaching

We hebben de inlining van de factorycache verbeterd om hot-paden beter te kunnen inlinen, wat leidt tot een snellere uitvoering.

Deze verbetering heeft geen invloed op de codegrootte, zoals hieronder wordt beschreven in geoptimaliseerde EH-code-gen, als uw toepassing intensief gebruikmaakt van C++-uitzonderingsafhandeling, kunt u uw binaire bestand verkleinen met behulp van de optie /d2FH4, 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 IInspectableimplementeert, kunt u dit nu doen met C++/WinRT. Zie COM-interfaces die IInspectableimplementeren.

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 in modulevergrendeling .

Ondersteuning voor niet-Windows-Runtime-foutinformatie

Bij sommige API's (zelfs sommige Windows Runtime-API's) worden fouten gerapporteerd zonder windows Runtime-API's voor foutoorsprongen te gebruiken. In dergelijke gevallen valt C++/WinRT nu terug op het gebruik van COM-foutgegevens. Zie C++/WinRT-ondersteuning voor niet-WinRT-foutinformatie.

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.

De efficiëntere hervatting van coroutines

C++/WinRT-coroutines presteren al goed, maar we blijven zoeken naar manieren om dat te verbeteren. Zie De schaalbaarheid van coroutine-hervattingverbeteren.

Nieuwe when_all en when_any asynchrone helpers

De when_all-hulpfunctie creëert 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 voor het toevoegen van de asynchrone helper when_any en voor het toevoegen van de asynchrone helper when_all.

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

Zie voor meer informatie over het C++/WinRT Visual Studio Extension (VSIX), het Microsoft.Windows.CppWinRT NuGet-pakketen het hulpprogramma cppwinrt.exe, waaronder het verkrijgen en installeren ervan, 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 foutopsporingsvisualisatie ondersteunt nu Visual Studio 2019; en blijven ondersteuning bieden voor Visual Studio 2017.
  • Er zijn talloze oplossingen voor fouten aangebracht.

Wijzigingen in het NuGet-pakket Microsoft.Windows.CppWinRT voor versie 2.0

  • Het hulpprogramma cppwinrt.exe is nu opgenomen in het Microsoft.Windows.CppWinRT NuGet-pakket en genereert platform-projectieheaders voor elk project op verzoek. Daarom is het cppwinrt.exe hulpprogramma niet langer afhankelijk van de Windows SDK (hoewel het hulpprogramma nog steeds om compatibiliteitsredenen bij de SDK wordt geleverd).
  • cppwinrt.exe genereert 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 het NuGet-pakket Microsoft.Windows.CppWinRT readme.
  • Er zijn talloze oplossingen voor fouten aangebracht.

Wijzigingen in C++/WinRT voor versie 2.0

Open source

Het hulpprogramma cppwinrt.exe neemt een Windows Runtime-metagegevensbestand (.winmd) en genereert daaruit een standaard C++-bibliotheek op basis van headerbestanden, die projecten de API's zoals beschreven in de metagegevens. Op die manier kunt u deze API's gebruiken vanuit uw C++/WinRT-code.

Dit hulpprogramma is nu een volledig opensource-project dat beschikbaar is op GitHub. Ga naar Microsoft/cppwinrt.

xlang-bibliotheken

Een volledig draagbare, header-only bibliotheek (voor het parseren van het ECMA-335-metagegevensformaat dat wordt gebruikt door Windows Runtime) vormt de basis van alle Windows Runtime- en xlang-tools voor de toekomst. We hebben ook het cppwinrt.exe hulpprogramma helemaal opnieuw herschreven met behulp van de xlang-bibliotheken. 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 hulpprogramma cppwinrt.exe zelf minder afhankelijkheden. Hierdoor is het veel flexibeler en bruikbaarder in meer scenario's, met name in beperkte buildomgevingen. Met name het is niet langer afhankelijk 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 in Windows 10, maar helemaal tot aan Windows 7 en zelfs Windows Vista. Als u dit wilt, kan uw oude buildserver met Windows 7 nu cppwinrt.exe uitvoeren om C++-headers voor uw project te genereren. Met een beetje werk kunt u zelfs C++/WinRT uitvoeren op Windows 7, als u dat interesseert.

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.0te versieren. De aanwezigheid van het kenmerk geeft ondersteunende tools aan dat uw implementatie geen uitzondering genereert (noch een falende HRESULT retourneert). 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 genereren van zowel de gebruikende als de ontwikkelingscode. Als u API-methoden of -eigenschappen hebt die feilloos zijn en u zich zorgen maakt over de grootte van de code, kunt u dit attribuut onderzoeken.

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 verminderen van de kosten van uitzonderingsafhandeling door het vermijden van onnodige unwind-informatie. 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 uitzonderingsafhandeling (EH) codegeneratie

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). Vanuit Visual Studio 2019 opvouwt de C++-compiler echter al deze catch-funclets en slaat deze alleen op die die uniek zijn. 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 opbouwverbeteringen

Het hulpprogramma cppwinrt.exe 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 in feite 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 handgeschreven in winrt/base.h. Het resultaat is dat de grootte van winrt/base.h in 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 Algemene eigenschappen>C++/WinRT>Geoptimaliseerde in op Ja. Dit heeft het effect van het toevoegen van <CppWinRTOptimized>true</CppWinRTOptimized> aan uw projectbestand. En het heeft hetzelfde effect als het toevoegen van de -opt[imize] switch bij het aanroepen van cppwinrt.exe vanaf de opdrachtregel.

Een nieuw project (van een projectsjabloon) gebruikt standaard -opt.

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. Het is niet nodig om te maken, make_selfof get_self als u gewoon het openbare API-oppervlak wilt gebruiken. Uw oproepen zullen worden gecompileerd tot directe oproepen naar de implementatie, en kunnen zelfs volledig worden geïnlineerd.

Zie Opt in to uniform construction en directe implementatietoegangvoor meer informatie en codevoorbeelden.

Type-wis fabriek

Deze optimalisatie vermijdt de #include afhankelijkheden in module.g.cpp, zodat deze niet telkens opnieuw hoeft te worden gecompileerd wanneer er één implementatieklasse verandert. Het resultaat is een verbeterde build-prestatie.

Slimmere en efficiëntere module.g.cpp voor grote projecten met meerdere bibliotheken

Het bestand module.g.cpp bevat nu ook twee extra composeerbare helpers met de naam winrt_can_unload_nowen 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 DLL-DllGetActivationFactory- en DllCanUnloadNow-handmatig samenstellen. Deze helpers maken het voor u veel gemakkelijker om dat te doen, door fouten met onjuiste oorsprong te voorkomen. De cppwinrt.exe-tool -lib-vlag kan ook worden gebruikt om elke afzonderlijke lib een eigen preambule te geven (in plaats van winrt_xxx), zodat de functies van elke lib individueel kunnen worden benoemd en dus 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 tijdelijk voor v2.0 een winrt/coroutine.h headerbestand nodig, maar dat is niet meer nodig. Omdat de asynchrone Windows Runtime-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 het beter onderhoudbaar en ondersteunbaar is, betekent dit dat coroutine-helpers zoals resume_foreground niet meer aan het einde van een specifieke naamruimteheader hoeven te worden toegevoegd. In plaats daarvan kunnen ze hun afhankelijkheden natuurlijker opnemen. Hierdoor kan resume_foreground niet alleen ondersteuning bieden voor het hervatten op een bepaalde Windows::UI::Core::CoreDispatcher, maar het kan nu ook worden gebruikt voor het hervatten op een bepaalde Windows::System::DispatcherQueue. 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 voorzien van [[nodiscard]], waardoor hun bruikbaarheid wordt verbeterd. Als u vergeet (of u niet realiseert dat u dat moet) co_await om ze te laten werken, dan produceren dergelijke fouten nu een compilerwaarschuwing vanwege [[nodiscard]].

Hulp bij het diagnosticeren van directe (stack)-toewijzingen

Aangezien de project- en implementatieklassenamen (standaard) hetzelfde zijn en alleen in namespace verschillen, is het mogelijk om de ene met de andere te verwarren en per ongeluk een implementatie op de stack te creëren, in plaats van gebruik te maken van de familie van hulpprogramma's. Dit kan in sommige gevallen moeilijk te diagnosticeren zijn, omdat het object kan worden vernietigd terwijl openstaande verwijzingen nog steeds in de vlucht zijn. Een assertie pikt dit nu op voor foutopsporingsversies. Hoewel de assertie geen stacktoewijzing in een coroutine detecteert, is het toch handig om de meeste dergelijke fouten te ondervangen.

Voor meer informatie, zie Diagnostiek van directe toewijzingen.

Verbeterde capture-helpers en variadic gedelegeerden

Met deze update wordt de beperking opgelost met de capture-helpers door ook projecttypen te ondersteunen. Dit komt nu en dan met de Interop API's van Windows Runtime, wanneer ze een geprojecteerd type retourneren.

Met deze update wordt ook ondersteuning toegevoegd voor get_strong en get_weak bij het maken van een variadic (niet-Windows Runtime)-gemachtigde.

Ondersteuning voor uitgestelde vernietiging en veilige QI tijdens vernietiging

Het is niet ongebruikelijk dat in de destructor van een runtime-klasseobject een methode wordt aangeroepen waarmee het aantal verwijzingen tijdelijk wordt verhoogd. Wanneer het aantal verwijzingen naar nul gaat, wordt het object een tweede keer vernietigd. In een XAML-toepassing moet u mogelijk een QueryInterface (QI) uitvoeren in een destructor om een opschonings-implementatie omhoog of omlaag in de hiërarchie aan te roepen. Maar de referentietelling van het object heeft al nul bereikt, waardoor QI ook een sprong in de referentietelling vormt.

Met deze update wordt ondersteuning toegevoegd voor het deboncen van de referentietelling, waarmee wordt gegarandeerd dat het nooit meer kan worden hersteld als het eenmaal nul bereikt; terwijl je nog steeds de mogelijkheid hebt om te QI'en voor elke tijdelijke variabele die je 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. Het is veilig voor u om de aanwijzer te QI-en zonder dat er een dubbele vernietiging plaatsvindt. Maar de nettowijziging in het aantal verwijzingen moet nul zijn op het punt dat u het object destructeert.

De retourwaarde van final_release kan worden void, een asynchroon bewerkingsobject zoals IAsyncActionof 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 onderstaande voorbeeld wordt final_release aangeroepen zodra de MainPage definitief wordt gereleased. Deze functie besteedt vijf seconden aan wachten (in de threadgroep) en wordt vervolgens hervat met behulp van de Dispatcher- van de pagina (waarvoor QI/AddRef/Release vereist is). Vervolgens wordt een resource op die UI-thread opgeschoond. En ten slotte wist het de unique_ptr, waardoor de destructor van de MainPage daadwerkelijk wordt aangeroepen. Zelfs in die destructor wordt DataContext aangeroepen. Hiervoor is een QI vereist voor IFrameworkElement.

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 vernietigingvoor meer informatie.

Verbeterde ondersteuning voor overname van één interface in COM-stijl

Naast het programmeren van Windows Runtime 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 Windows Runtime; maar het is vereist voor sommige COM-implementaties.

Juiste verwerking van out parameters

Het kan lastig zijn om met out params 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; of deze parameters binnenkomen via een taalprojectie, of van een COM-ontwikkelaar die de onbewerkte ABI gebruikt en die de fout maakt dat variabelen niet consistent worden geïnitialiseerd. In beide gevallen doet C++/WinRT nu het juiste als het gaat om het overdragen van geprojecteerde typen aan de ABI (door te onthouden om resources vrij te geven) en als het gaat om het nulstellen of uitvagen van parameters die vanuit de ABI binnenkomen.

Gebeurtenissen verwerken nu op betrouwbare wijze ongeldige tokens

De winrt::event implementatie verwerkt nu probleemloos het geval waarin de methode verwijderen 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 coroutinetype te implementeren, kan lokale variabelen in de coroutine worden vernietigd na de coroutine retourneert/voltooit (in plaats van vóór de definitieve schorsing). 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
brekende wijziging. Voor het compileren is C++/WinRT niet afhankelijk van headers van de Windows SDK. Zie Isolatie van Windows SDK-headerbestandenhieronder.
De indeling van het Visual Studio-projectsysteem is gewijzigd. Zie Hoe je jouw C++/WinRT-project kunt heroriënteren naar 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 {Binding} markeringsextensie gebruiken met uw C++/WinRT-runtimeklassen. Zie Overzicht van gegevensbindingvoor meer informatie en codevoorbeelden.
Met ondersteuning voor het annuleren van een coroutine kunt u een annuleringsaanroep registreren. Zie voor meer informatie en codevoorbeelden Het annuleren van een asynchrone bewerking en annuleringscallbacks.
Wanneer u een gemachtigde maakt die verwijst naar een lidfunctie, kunt u een sterke of zwakke verwijzing naar het huidige object tot stand brengen (in plaats van een onbewerkte deze aanwijzer) op het punt waar de handler is geregistreerd. Voor meer informatie en codevoorbeelden, zie de subsectie Als u een lidfunctie als een gedelegeerde gebruikt in de sectie Veilig toegang krijgen tot de this-pointer met een gedelegeerde voor gebeurtenisafhandeling.
Fouten worden opgelost die zijn ontdekt door de verbeterde conformiteit van Visual Studio met 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 wordt mijn nieuwe project niet gecompileerd? niet langer ondervinden. Ik gebruik Visual Studio 2017 (versie 15.8.0 of hoger) en SDK-versie 17134

Andere wijzigingen.

  • brekende wijziging. winrt::get_abi(winrt::hstring const&) retourneert void* nu in plaats van HSTRING. U kunt static_cast<HSTRING>(get_abi(my_hstring)); gebruiken om een HSTRING te verkrijgen. Zie Samenwerken met de HSTRING-van de ABI.
  • brekende wijziging. winrt::put_abi(winrt::hstring&) retourneert nu void** in plaats van HSTRING*. U kunt reinterpret_cast<HSTRING*>(put_abi(my_hstring)); gebruiken om een HSTRING* op te halen. Zie Samenwerken met de HSTRING-van de ABI.
  • brekende wijziging. HRESULT wordt nu weergegeven als winrt::hresult. Als u een HRESULT nodig hebt (om typecontrole uit te voeren of om typeeigenschappen te ondersteunen), static_cast kunt u een winrt::hresult. Anders wordt winrt::hresult geconverteerd naar HRESULT, zolang u unknwn.h opneemt voordat u C++/WinRT-headers opneemt.
  • brekende wijziging. GUID wordt nu geprojecteerd als winrt::guid. Voor API's die u implementeert, moet u winrt::guid gebruiken voor GUID-parameters. In het andere geval wordt winrt::guid geconverteerd naar GUID, zolang u unknwn.h opneemt voordat u C++/WinRT-headers opneemt. Zie Samenwerking met de ABI's GUID-struct.
  • brekende 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 handlewaarde wilt toewijzen, roept u in plaats daarvan de handle_type::attach-functie aan.
  • brekende wijziging. De handtekeningen van WINRT_CanUnloadNow en WINRT_GetActivationFactory zijn gewijzigd. U moet deze functies helemaal niet declareren. Neem in plaats daarvan winrt/base.h (die automatisch wordt opgenomen als u C++/WinRT Windows-naamruimteheaderbestanden opneemt) om de declaraties van deze functies op te nemen.
  • Voor de winrt::clock structzijn from_FILETIME/to_FILETIME verouderd 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 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 het hulpprogramma cppwinrt.exe niet meer recursief naar .winmd bestanden. Het hulpprogramma cppwinrt.exe verwerkt nu ook duplicaten intelligenter, waardoor het toleranter is voor gebruikersfouten en slecht gevormde .winmd bestanden.
  • Verharde slimme aanwijzers. Voorheen konden de evenementannuleerders niet annuleren wanneer ze via verplaatsing een nieuwe waarde toegewezen kregen. Dit heeft geholpen bij het ontdekken van een probleem waarbij slimme aanwijzerklassen niet betrouwbaar zelftoewijzing afhandelen; geroot in de winrt::com_ptr structsjabloon. Zijn winrt::com_ptr is gecorrigeerd en de gebeurtenisrevokers zijn aangepast om de move-semantiek correct te verwerken, zodat ze bij toewijzing intrekken.

Belangrijk

Belangrijke wijzigingen zijn aangebracht in de C++/WinRT Visual Studio Extension (VSIX), beide in versie 1.0.181002.2 en 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 en het niet aan een andere bibliotheek over te laten om ze voor u op te nemen.

Op dit moment zijn de enige uitzonderingen op bestandsisolatie van Windows SDK-headers voor intrinsieke kenmerken en numerieke gegevens. Er zijn geen bekende problemen met deze laatste resterende afhankelijkheden.

In uw project kunt u de interoperabiliteit met de Windows SDK-headers desgewenst opnieuw inschakelen. U kunt bijvoorbeeld een COM-interface implementeren (geroot in IUnknown). Neem bijvoorbeeld 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 ontwerpen 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 voor het retargeten van uw project die waarschijnlijk resulteert in de minste compiler- en linkerproblemen is ook de meest arbeidsintensieve. 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 zijn gedeeltes van uw oude .vcxproj- en .vcxproj.filters-bestanden die u eenvoudig kunt overnemen, zodat u geen bestanden hoeft toe te voegen in Visual Studio.

Er zijn echter twee andere manieren om uw project opnieuw in te stellen in Visual Studio.

  • Ga naar projecteigenschap Algemeen>Windows SDK-versieen selecteer Alle configuraties en Alle platforms. Stel Windows SDK-versie in op de versie waarop u zich wilt richten.
  • Klik in Solution Explorermet de rechtermuisknop op het projectknooppunt, klik op Projecten opnieuw, kies de gewenste versie(s) 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 'fout C2039: 'IUnknown': maakt geen deel uit van ''global namespace''', voegt u #include <unknwn.h> aan het begin van uw pch.h-bestand toe (voordat u C++/WinRT-headers opneemt).

Mogelijk moet u daarna ook #include <hstring.h> toevoegen.

Als de C++-linker "fout LNK2019: niet-opgelost extern symbool _WINRT_CanUnloadNow@0 waarop wordt verwezen in functie _VSDesignerCanUnloadNow@0" produceert, kunt u dit oplossen door #define _VSDESIGNER_DONT_LOAD_AS_DLL toe te voegen aan uw pch.h file.