A C++/WinRT újdonságai

A C++/WinRT későbbi verzióinak megjelenésekor ez a témakör ismerteti az újdonságokat és a megváltozott változásokat.

A legutóbbi fejlesztések/kiegészítések összesítése 2020 márciusától

Akár 23% rövidebb buildelési idő

A C++/WinRT és a C++ fordítócsapatok együttműködve mindent megtesznek a létrehozási idő lerövidítése érdekében. A fordítóelemzésen áthatoltuk, hogy a C++/WinRT belső elemei hogyan strukturálhatók át, hogy a C++ fordító kiküszöbölje a fordítási idő terhelését, valamint hogy maga a C++ fordító hogyan fejleszthető a C++/WinRT-kódtár kezeléséhez. A C++/WinRT a fordítóhoz lett optimalizálva; és a fordító a C++/WinRT-hez lett optimalizálva.

Vegyük például egy előre lefordított fejléc (PCH) létrehozásának legrosszabb esetét, amely minden egyes C++/WinRT-vetítési névtérfejlécet tartalmaz.

verzió PCH-méret (bájt) Idő (ek)
C++/WinRT júliustól a Visual C++ 16.3-val 3,004,104,632 31
A C++/WinRT 2.0.200316.3-os verziója a Visual C++ 16.5-ös verziójával 2,393,515,336 24

20% méretcsökkenés, és 23% a buildelési idő csökkentése.

Továbbfejlesztett MSBuild-támogatás

Sok munkát fektettünk az MSBuild támogatásának fejlesztésébe számos különböző forgatókönyv esetében.

Még gyorsabb gyári gyorsítótárazás

Továbbfejlesztettük a gyári gyorsítótárat a jobb beágyazott gyorselérési utak érdekében, ami gyorsabb végrehajtáshoz vezet.

Ez a fejlesztés nincs hatással a kódméretre — ahogy azt az alábbi Optimalizált EH-kódgenerálás szakaszban ismertetjük, ha az alkalmazása nagymértékben használ C++ kivételkezelést, akkor a bináris méretét csökkentheti a /d2FH4 kapcsoló használatával, amely alapértelmezés szerint be van kapcsolva a Visual Studio 2019 16.3-as és újabb verzióival létrehozott új projektekben.

Hatékonyabb boxolás

XAML-alkalmazásokban való használat esetén a winrt::box_value mostantól hatékonyabb (lásd: Boxing and unboxing). Azok az alkalmazások, amelyek sok ökölvívást végeznek, a kódméret csökkenését is észlelik.

Az IInspectable felületet megvalósító COM-interfészek implementálásának támogatása

Ha egy (nemWindows-Runtime) COM-felületet kell implementálnia, amely éppen az IInspectable implementálásához szükséges, akkor ezt most a C++/WinRT használatával teheti meg. Lásd az IInspectable-t implementáló COM-felületeket.

Modulzárolási fejlesztések

A modulzárolás szabályozása mostantól lehetővé teszi az egyéni üzemeltetési forgatókönyveket és a modulszintű zárolás teljes megszüntetését is. Lásd a modulzárolási fejlesztéseket.

A nem Windows Runtime-eredetű hibainformációk támogatása

Egyes API-k (még Windows-futtatókörnyezet API-k is) Windows-futtatókörnyezet hibakeresési API-k használata nélkül jelentik a hibákat. Ilyen esetekben a C++/WinRT mostantól visszaesik a COM-hibainformációk használatára. Lásd: A nem WinRT típusú hibainformációk C++/WinRT-támogatása.

C++ modul támogatásának engedélyezése

A C++ modul támogatása visszatért, de csak kísérleti formában. A funkció még nem fejeződött be a C++ fordítóban.

Hatékonyabb coroutine újraindulása

A C++/WinRT coroutines már jól teljesít, de továbbra is keressük a megoldási lehetőségeket. Lásd: A koroutin újraindulásának méretezhetőségének javítása.

Új when_all és when_any aszinkron segítők

A(z) when_all segédfüggvény egy IAsyncAction objektumot hoz létre, amely akkor fejeződik be, amikor az összes megadott awaitelhető objektum befejeződik. A when_any segédfüggvény egy IAsyncAction műveletet hoz létre, amely akkor fejeződik be, amikor a megadott várható objektumok bármelyike befejeződött.

Lásd: A when_any aszinkron segédfüggvény hozzáadása és A when_all aszinkron segédfüggvény hozzáadása.

Egyéb optimalizálások és kiegészítések

Emellett számos hibajavítást és kisebb optimalizálást és kiegészítést vezettek be, beleértve a hibakeresés egyszerűsítését és a belső és alapértelmezett implementációk optimalizálását célzó különböző fejlesztéseket. A teljes listát a következő hivatkozáson találja: https://github.com/microsoft/xlang/pulls?q=is%3Apr+is%3Aclosed.

Hírek és változások a C++/WinRT 2.0-ban

A C++/WinRT Visual Studio-bővítményről (VSIX), a Microsoft.Windows.CppWinRT NuGet-csomagról és a(z) cppwinrt.exe eszközről — beleértve azok beszerzésének és telepítésének módját is — további információkért lásd: A Visual Studio C++/WinRT, XAML, a VSIX-bővítmény és a NuGet-csomag támogatása.

A 2.0-s verzió C++/WinRT Visual Studio bővítményének (VSIX) módosítása

  • A hibakereső vizualizáló mostantól a Visual Studio 2019-et is támogatja, miközben továbbra is támogatja a Visual Studio 2017-et.
  • Számos hibajavítás történt.

A Microsoft.Windows.CppWinRT NuGet-csomag 2.0-s verziójának változásai

  • A cppwinrt.exe eszköz mostantól a Microsoft.Windows.CppWinRT NuGet-csomag része, és igény szerint platformprojekciós fejléceket hoz létre minden projekthez. Következésképpen az cppwinrt.exe eszköz már nem függ a Windows SDK-tól (bár a szerszám kompatibilitási okokból továbbra is az SDK-val szállít).
  • cppwinrt.exe Mostantól az egyes platformok/konfigurációspecifikus köztes mappák ($IntDir) alá vetítésfejléceket hoz létre a párhuzamos buildek engedélyezéséhez.
  • A C++/WinRT buildtámogatás (props/targets) már teljes mértékben dokumentálva van, ha manuálisan szeretné testre szabni a projektfájlokat. Lásd a Microsoft.Windows.CppWinRT NuGet-csomag readme fájlját.
  • Számos hibajavítás történt.

A C++/WinRT módosítása a 2.0-s verzióhoz

Nyílt forráskód

Az cppwinrt.exe eszköz egy Windows-futtatókörnyezet metaadatfájlt (.winmd) használ, és egy fejlécfájl-alapú standard C++ kódtárat hoz létre belőle, amely a metaadatokban leírt API-kat projekteli. Így ezeket az API-kat a C++/WinRT-kódból is felhasználhatja.

Ez az eszköz most már egy teljes egészében nyílt forráskód projekt, amely GitHub érhető el. Látogasson el a Microsoft/cppwinrt oldalra.

xlang-kódtárak

A Windows-futtatókörnyezet által használt ECMA-335 metaadatformátum elemzésére szolgáló, teljesen hordozható, kizárólag fejlécfájlokból álló kódtár képezi majd az összes Windows-futtatókörnyezet- és xlang-eszköz alapját a jövőben. Figyelemre méltó, hogy a cppwinrt.exe eszközt is teljesen újraírtuk az xlang könyvtárak felhasználásával. Ez sokkal pontosabb metaadat-lekérdezéseket biztosít, és a C++/WinRT nyelvi előrejelzéssel kapcsolatos néhány régóta fennálló problémát old meg.

Kevesebb függőség

Az xlang metaadat-olvasója miatt maga az cppwinrt.exe eszköz kevesebb függőséget vesz fel. Ez sokkal rugalmasabbá teszi, és több forgatókönyvben is használható – különösen korlátozott buildkörnyezetekben. Fontos, hogy többé már nem támaszkodik a(z) RoMetadata.dll elemre.   Ezek a cppwinrt.exe 2.0 függőségei.  

  • ADVAPI32.dll
  • KERNEL32.dll
  • SHLWAPI.dll
  • XmlLite.dll

Ezek a DLL-ek nem csak Windows 10 érhetők el, hanem egészen a Windows 7 ig, sőt Windows Vista is. Ha szeretné, a régi, Windows 7 futó buildkiszolgáló mostantól képes Ccppwinrt.exe++ fejléceket létrehozni a projekthez. Egy kis munkával a C++/WinRT-t is futtathatja Windows 7, ha ez érdekli.

Hasonlítsa össze a fenti listát ezekkel a függőségekkel, amelyekkel cppwinrt.exe az 1.0 rendelkezik.

  • 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

A Windows-futtatókörnyezet noexcept attribútum

A Windows-futtatókörnyezet egy új [noexcept] attribútummal rendelkezik, amellyel a metódusokat és tulajdonságokat a MIDL 3.0-ban díszítheti. Az attribútum jelenléte azt jelzi a támogató eszközöknek, hogy az implementáció nem ad kivételt (és nem ad vissza sikertelen HRESULT-t). Ez lehetővé teszi, hogy a nyelvi előrejelzések optimalizálják a kódlétrehozást azáltal, hogy elkerülik az alkalmazás bináris felületének (ABI)-hívások támogatásához szükséges kivételkezelési többletterhelést, amely esetleg meghiúsulhat.

A C++/WinRT kihasználja ezt azáltal, hogy C++ noexcept implementációkat hoz létre mind a fogyasztó, mind a szerzői kódhoz. Ha vannak olyan hibamentes API-metódusai vagy -tulajdonságai, és a kódméret is fontos szempont, akkor érdemes megvizsgálnia ezt az attribútumot.

Optimalizált kódgenerálás

A C++/WinRT mostantól még hatékonyabb C++ forráskódot hoz létre (a színfalak mögött), hogy a C++ fordító a lehető legkisebb és leghatékonyabb bináris kódot hozza létre. Számos fejlesztés célja a kivételkezelés költségeinek csökkentése a szükségtelen visszatekerés elkerülése érdekében. A nagy mennyiségű C++/WinRT-kódot használó bináris fájlok nagyjából 4% csökkentik a kód méretét. A kód a csökkentett utasításszám miatt hatékonyabb is (gyorsabban fut).

Ezek a fejlesztések az Ön számára is elérhető új interop funkcióra támaszkodnak. Az erőforrás-tulajdonosok összes C++/WinRT-típusa tartalmaz egy konstruktort, amely közvetlenül veszi át a tulajdonjogot, elkerülve az előző kétlépéses megközelítést.

ABI::Windows::Foundation::IStringable* raw = ...

IStringable projected(raw, take_ownership_from_abi);

printf("%ls\n", projected.ToString().c_str());

Optimalizált kivételkezelési (EH) kódgenerálás

Ez a módosítás kiegészíti a Microsoft C++ optimalizáló csapat által a kivételkezelés költségeinek csökkentése érdekében végzett munkát. Ha nagy mértékben használ alkalmazásbináris felületeket (ABI-ket) — például a COM-ot — a kódjában, akkor sok, ezt a mintát követő kóddal fog találkozni.

int32_t Function() noexcept
{
    try
    {
        // code here constitutes unique value.
    }
    catch (...)
    {
        // code here is always duplicated.
    }
}

A C++/WinRT maga hozza létre ezt a mintát minden implementált API-hoz. Több ezer API-függvény esetén az itt található optimalizálás jelentős lehet. A múltban az optimalizáló nem észlelte, hogy ezek a fogási blokkok mind azonosak, ezért sok kódot duplikált az egyes ABI-k körül (ami hozzájárult ahhoz a meggyőződéshez, hogy a rendszerkód kivételeinek használata nagy bináris fájlokat eredményez). A Visual Studio 2019-től kezdődően azonban a C++ fordító összevonja az összes catch funcletet, és csak az egyedi példányokat tárolja. Ennek eredménye a kódméret további, összességében 18%-os csökkenése azon binárisoknál, amelyek nagymértékben támaszkodnak erre a mintára. Az EH-kód nemcsak hatékonyabb, mint a visszatérési kódok használata, hanem a nagyobb bináris fájlok miatti aggodalom is a múlté.

Növekményes buildfejlesztések

Az cppwinrt.exe eszköz most összehasonlítja a létrehozott fejléc/forrásfájl kimenetét a lemezen lévő meglévő fájlok tartalmával, és csak akkor írja ki a fájlt, ha a fájl valójában megváltozott. Ez jelentős időt takarít meg a lemez I/O-jával, és biztosítja, hogy a C++ fordító ne tekintse "piszkosnak" a fájlokat. Ennek az az eredménye, hogy az újrafordítás sok esetben elkerülhető vagy csökkenthető.

Az általános felületek most már mind létre lettek hozva

Az xlang metaadat-olvasója miatt a C++/WinRT mostantól minden paraméteres vagy általános felületet létrehoz a metaadatokból. Az olyan felületek, mint a Windows::Foundation::Collections::IVector<T>, most már metaadatokból jönnek létre, nem pedig kézzel írtak.winrt/base.h Az eredmény az, hogy a winrt/base.h mérete a felére csökkent, és az optimalizálások közvetlenül a kódban jönnek létre (amit a kézzel készített megközelítéssel nehéz volt megvalósítani).

Fontos

A megadott példában szereplőhöz hasonló felületek mostantól a megfelelő névtérfejlécekben jelennek meg, nem pedig a(z) winrt/base.h elemben. Ha tehát még nem tette meg, a felület használatához meg kell adnia a megfelelő névtérfejlécet.

Összetevők optimalizálása

Ez a frissítés több további, a C++/WinRT-hez készült opt-in optimalizálás támogatását is támogatja, az alábbi szakaszokban leírtak szerint. Mivel ezek az optimalizálások kompatibilitástörő változások (amelyek támogatásához előfordulhat, hogy kisebb módosításokat kell végrehajtania), kifejezetten be kell kapcsolnia őket. A Visual Studióban állítsa a projekt Common Properties>C++/WinRT>Optimized tulajdonságát Igen értékre. Ennek az a hatása, hogy hozzáadja a(z) <CppWinRTOptimized>true</CppWinRTOptimized> elemet a projektfájlhoz. És ugyanolyan hatással van, mint a -opt[imize] kapcsoló hozzáadása a parancssorból való cppwinrt.exe meghíváskor.

Alapértelmezés szerint egy új projekt (projektsablonból) lesz használva -opt .

Egységes építés és közvetlen megvalósítási hozzáférés

Ez a két optimalizálás lehetővé teszi, hogy az összetevő közvetlen hozzáférést biztosít a saját implementációs típusaihoz, még akkor is, ha csak a tervezett típusokat használja. Nincs szükség a make, make_self és get_self használatára, ha egyszerűen csak a nyilvános API-felületet szeretné használni. A hívásai közvetlenül az implementációba irányuló hívásokká fordulnak le, és ezek akár teljesen inline-olódhatnak is.

További információt és példakódokat az egységes építés és a közvetlen megvalósítási hozzáférés engedélyezése című témakörben talál.

Típustörlésű gyárak

Ez az optimalizálás elkerüli a #include függőségeket module.g.cpp , hogy ne kelljen minden alkalommal újrafordítást végrehajtani, amikor egyetlen implementációs osztály is megváltozik. Ennek eredménye a jobb buildteljesítmény.

Intelligensebb és hatékonyabb module.g.cpp a több libet tartalmazó nagy projektekhez

A module.g.cpp fájl két további, winrt_can_unload_now és winrt_get_activation_factory nevű összeírható segédet is tartalmaz. Ezeket olyan nagyobb projektekhez tervezték, amelyekben egy DLL több libből áll, amelyek mindegyike saját futtatókörnyezeti osztályokkal rendelkezik. Ebben a helyzetben kézzel kell összekapcsolnia a DLL DllGetActivationFactory és DllCanUnloadNow függvényeit. Ezek a segítők sokkal egyszerűbbé teszik ezt, mivel elkerülik a hamis eredethibákat. Az cppwinrt.exe eszköz -lib jelzője arra is használható, hogy minden egyes könyvtár saját preambulumot kapjon (a winrt_xxx helyett), így az egyes könyvtárak függvényei külön-külön elnevezhetők, és ezáltal egyértelműen kombinálhatók legyenek.

Korutin támogatása

A coroutine támogatása automatikusan megjelenik. Korábban a támogatás több helyen volt, ami túl korlátozónak tűnt. Ezután ideiglenesen a 2.0-s verzióhoz fejlécfájlra winrt/coroutine.h volt szükség, de erre már nincs szükség. Mivel a Windows-futtatókörnyezet aszinkron interfészeit most már generálják, nem pedig kézzel írják, ezért most már a winrt/Windows.Foundation.h alatt találhatók. Amellett, hogy karbantarthatóbb és könnyebben támogatható, azt is jelenti, hogy a korutinsegítőket, például a resume_foreground-ot, többé nem kell egy adott névtérfejléc végére hozzáfűzni. Ehelyett természetesebb módon belefoglalhatják a függőségeiket. Ez továbbá lehetővé teszi, hogy a resume_foreground ne csak egy adott Windows::UI::Core::CoreDispatcher esetén támogassa a folytatást, hanem mostantól egy adott Windows::System::DispatcherQueue esetén is. Korábban csak egy támogatott; de nem mindkettő, mivel a definíció csak egy névtérben található.

Íme egy példa a DispatcherQueue támogatására.

...
#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);
}

A korutinsegítők mostantól a [[nodiscard]] elemmel is el vannak látva, ami javítja a használhatóságukat. Ha elfelejti (vagy nem veszi észre, hogy kell) co_await őket ahhoz, hogy működjenek, akkor a(z) [[nodiscard]] miatt az ilyen hibák most fordítói figyelmeztetést eredményeznek.

Segítség a közvetlen (verem)foglalások diagnosztizálásához

Mivel a projekciós és az implementációs osztálynevek (alapértelmezés szerint) megegyeznek, és csak a névterük különbözik, könnyen összetéveszthetők, és véletlenül a veremen hozhat létre implementációt a make segédfüggvény-család használata helyett. Ez bizonyos esetekben nehéz lehet diagnosztizálni, mert az objektum megsemmisülhet, miközben a függőben lévő hivatkozások még mindig repülnek. Ezt most egy assert észleli a hibakeresési buildekben. Bár az állítás nem észleli a veremfoglalást egy koroutinban, mégis hasznos a legtöbb ilyen hiba észlelésében.

További információkért lásd: A közvetlen lefoglalások diagnosztizálása.

Továbbfejlesztett rögzítési segítők és variadikus meghatalmazottak

Ez a frissítés az előre jelzett típusok támogatásával is kijavítja a rögzítési segítők korlátozását. Ez időről időre felmerül a Windows-futtatókörnyezet interop API-knál, amikor azok egy leképezett típust adnak vissza.

Ez a frissítés get_strong ésget_weak is támogatja a variadikus (nem Windows-futtatókörnyezet) meghatalmazottak létrehozásakor.

A késleltetett megsemmisítés és a biztonságos QI támogatása a megsemmisítés során

Nem ritka, hogy egy futásidejű osztály objektumának destruktorában olyan metódust hívnak meg, amely ideiglenesen megnöveli a hivatkozásszámot. Amikor a referenciaszámláló újra nullára csökken, az objektum másodszor is megsemmisül. Az XAML-alkalmazásokban előfordulhat, hogy egy destruktorban el kell végeznie egy QueryInterface (QI) műveletet, hogy valamilyen karbantartási implementációt hívjon fel vagy le a hierarchiában. Az objektum hivatkozási száma azonban már elérte a nullát, így a QI is hivatkozásszám-visszapattanást jelent.

Ez a frissítés bevezeti a referenciaszám nullára csökkenésének biztonságos kezelését, biztosítva, hogy amint eléri a nullát, többé ne lehessen újra növelni; ugyanakkor továbbra is lehetővé teszi, hogy a megsemmisítés során QI-t hívjon meg az ideiglenesen szükséges interfészekhez. Ez az eljárás bizonyos XAML-alkalmazásokban/-vezérlőkben megkerülhetetlen, és a C++/WinRT mostantól ellenállóvá vált vele szemben.

Halaszthatja a megsemmisítést, ha statikus final_release függvényt ad meg a megvalósítási típushoz. Az objektumra mutató utolsó megmaradt mutató std::unique_ptr formájában kerül átadásra az Ön final_release függvényének. Ezután dönthet úgy, hogy a mutató tulajdonjogát más környezetbe helyezi át. Biztonságosan végezhet QI-hívást a mutatón anélkül, hogy kettős megsemmisítést idézne elő. Azonban a hivatkozásszám nettó változásának nullának kell lennie abban a pillanatban, amikor megsemmisíted az objektumot.

A final_release visszatérési értéke lehet voidaszinkron műveleti objektum, például IAsyncAction vagy 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.
    }
};

Az alábbi példában a MainPage kiadását követően (az utolsó alkalommal) final_release lesz meghívva. Ez a függvény öt másodpercig várakozik (a szálkészletben), majd az oldal Dispatcherét használva folytatódik (amihez a QI/AddRef/Release szükséges a működéshez). Ezután megtisztít egy erőforrást az adott felhasználói felületi szálon. Végül törli a unique_ptr, ami miatt a MainPage destruktort ténylegesen meghívják. Még ebben a destruktorban is meghívják a DataContextet , amely QI-t igényel az IFrameworkElementhez.

Nem kell a final_release koroutinként implementálnia. De ez működik, és nagyon egyszerűvé teszi a pusztítás áthelyezését egy másik szálra, ami ebben a példában történik.

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;
    }
};

További információ: Késleltetett megsemmisítés.

Továbbfejlesztett támogatás a COM-stílusú egyfelület-örökléshez

A Windows-futtatókörnyezet programozás mellett a C++/WinRT com-only API-k készítésére és felhasználására is használható. Ez a frissítés lehetővé teszi egy COM-kiszolgáló implementálását, ahol létezik interfészhierarchia. Ez nem szükséges a Windows-futtatókörnyezet, de bizonyos COM-implementációkhoz szükséges.

Paramok helyes kezelése out

Nehéz lehet paramokkal dolgozni, különösen Windows-futtatókörnyezet tömbökkelout. Ezzel a frissítéssel a C++/WinRT jelentősen robusztusabb és ellenállóbb a hibákkal szemben, ha paramokról és tömbökről van szó out ; függetlenül attól, hogy ezek a paraméterek nyelvi kivetítéssel érkeznek-e, vagy egy olyan COM-fejlesztőtől, aki a nyers ABI-t használja, és hibát követ el, hogy nem inicializálja a változókat következetesen. A C++/WinRT mindkét esetben helyesen jár el az ABI-nak előrejelzett típusok átadásakor (az erőforrások kiadásának megjegyzésével), valamint az ABI-n keresztül érkező paraméterek nullázása vagy törlésekor.

Az események mostantól megbízhatóan kezelik az érvénytelen tokeneket

A winrt::event implementáció mostantól elegánsan kezeli azt az esetet, amikor az eltávolítási metódus meghívása érvénytelen jogkivonat-értékkel történik (ez az érték nem szerepel a tömbben).

A koroutin helyi változói elpusztulnak, mielőtt a koroutin visszatér

A koroutin típus hagyományos implementálásának módja lehetővé teheti a koroutinon belüli helyi változók megsemmisítését a koroutin visszatérése/befejezése után (a végleges szuszpenzió előtt). A pincérek újrakezdését a végleges felfüggesztésig elhalasztják, hogy elkerüljék ezt a problémát, és egyéb előnyöket halmozhassanak fel.

Hírek és változások Windows SDK 10.0.17763.0-s verziójában (Windows 10, 1809-es verzió)

Az alábbi táblázat a C++/WinRT híreit és változásait tartalmazza a Windows SDK 10.0.17763.0-s verziójában (Windows 10, 1809-es verzió).

Új vagy módosított funkció További információk
Kompatibilitástörő változás. A fordításhoz a C++/WinRT nem függ a Windows SDK fejlécétől. Lásd alább Windows SDK-fejlécfájlok elkülönítését.
A Visual Studio projektrendszer formátuma megváltozott. Tekintse meg a C++/WinRT-projekt újrakonfigurálását a Windows SDK egy későbbi verziójára az alábbiakban.
Vannak új függvények és alaposztályok, amelyek segítenek átadni egy gyűjteményobjektumot egy Windows-futtatókörnyezet függvénynek, vagy saját gyűjteménytulajdonságokat és gyűjteménytípusokat implementálni. Tekintse meg a C++/WinRT-lel rendelkező gyűjteményeket.
A {Binding} korrektúrakiterjesztést a C++/WinRT futtatókörnyezeti osztályokkal használhatja. További információkért és példakódokért tekintse meg az adatkötés áttekintését.
A koroutin lemondásának támogatása lehetővé teszi a lemondási visszahívás regisztrálását. További információ és példakód: Aszinkron művelet megszakítása és visszahívások lemondása.
Tagfüggvényre mutató delegált létrehozásakor a kezelő regisztrálásának pontján erős vagy gyenge hivatkozást hozhat létre az aktuális objektumhoz (nyers this mutató helyett). További információkért és kódpéldákért lásd a A this mutató biztonságos elérése eseménykezelő delegátummal szakasz Tagfüggvény használata delegátumként című alszakaszát.
Kijavítottuk a hibákat, amelyeket Visual Studio A C++ szabványnak való jobb megfelelése derített fel. Az LLVM és a Clang eszközlánc is jobban használható a C++/WinRT szabványoknak való megfelelésének ellenőrzéséhez. A jövőben már nem fog találkozni a(z) Miért nem fordul le az új projektem? Visual Studio 2017-et (15.8.0-s vagy újabb verzió) és 17134-es SDK-verziót használok című témakörben ismertetett problémával.

Egyéb módosítások.

  • Kompatibilitástörő változás. winrt::get_abi(winrt::hstring const>) most ad vissza void* ahelyett, hogy HSTRING. A static_cast<HSTRING>(get_abi(my_hstring)); használatával lekérhet egy HSTRINGet. Lásd: Az ABI HSTRING típusával való együttműködés.
  • Kompatibilitástörő változás. winrt::put_abi(winrt::hstring&) mostantól void** ad vissza HSTRING* helyett. A(z) reinterpret_cast<HSTRING*>(put_abi(my_hstring)); használatával lekérhet egy HSTRING*-t. Lásd: Az ABI HSTRING típusával való együttműködés.
  • Kompatibilitástörő változás. A HRESULT mostantól winrt::hresult lesz. Ha HRESULT-ra van szüksége (a típusellenőrzéshez vagy a típustulajdonságok támogatásához), akkor static_cast parancsot is használhatja. Ellenkező esetben a winrt::hresult HRESULT-tá konvertálódik, feltéve, hogy az unknwn.h elemet még azelőtt beilleszti, hogy bármilyen C++/WinRT-fejlécet felvenne.
  • Kompatibilitástörő változás. A GUID mostantól winrt::guid néven van kivetítve. Az Ön által implementált API-k esetében a GUID-paraméterekhez a winrt::guid típust kell használnia. Ellenkező esetben a winrt::guid GUID-dé konvertálódik, feltéve, hogy a C++/WinRT-fejlécek beillesztése előtt beilleszti a(z) unknwn.h elemet. Lásd: Együttműködés az ABI GUID-struktúrájával.
  • Kompatibilitástörő változás. A winrt::handle_type konstruktort explicitsé tették (most már nehezebb helytelen kódot írni vele). Ha nyers leíróértéket kell hozzárendelnie, hívja inkább a handle_type::attach függvényt .
  • Kompatibilitástörő változás. A WINRT_CanUnloadNow és WINRT_GetActivationFactory aláírása megváltozott. Ezeket a függvényeket egyáltalán nem szabad deklarálni. Ehelyett foglalja bele az winrt/base.h fejlécet (amely automatikusan belekerül, ha a C++/WinRT Windows-névtérhez tartozó bármely fejlécfájlt belefoglalja), hogy e függvények deklarációi is bekerüljenek.
  • A winrt::clock struktúra esetében a from_FILETIME/to_FILETIME a from_file_time/to_file_time javára elavultnak számítanak.
  • Egyszerűsített API-k, amelyek IBuffer-paramétereket várnak. A legtöbb API a gyűjteményeket vagy tömböket részesíti előnyben. De úgy éreztük, hogy egyszerűbbé kell tenni az IBufferre támaszkodó API-k meghívását. Ez a frissítés közvetlen hozzáférést biztosít az IBuffer-implementáció mögötti adatokhoz. Ugyanazt az adatelnevezési konvenciót használja, mint amelyet a C++ standard kódtár-tárolók használnak. Ez a konvenció a hagyományosan nagybetűvel kezdődő metaadat-névvel való ütközést is elkerüli.
  • Továbbfejlesztett kódlétrehozás: különböző fejlesztések a kódméret csökkentéséhez, a kódolás javításához és a gyári gyorsítótárazás optimalizálásához.
  • Eltávolítva a szükségtelen rekurziót. Ha a parancssor egy mappára hivatkozik egy adott .winmdhelyett, az cppwinrt.exe eszköz már nem keres rekurzívan .winmd fájlokat. Az cppwinrt.exe eszköz mostantól intelligensebben kezeli az ismétlődéseket, így rugalmasabbá válik a felhasználói hibákkal és a rosszul formázott .winmd fájlokkal szemben.
  • Edzett intelligens mutatók. Korábban az esemény-visszavonók nem vonták vissza az új érték áthelyezésekor. Ez segített feltárni azt a problémát, amely miatt az intelligens mutatóosztályok nem kezelték megbízhatóan az önkiosztást; a winrt::com_ptr struct sablonban gyökerezik. A winrt::com_ptr-t javították, és az esemény-visszavonó objektumokat úgy módosították, hogy helyesen kezeljék az áthelyezési szemantikát, így hozzárendeléskor visszavonódnak.

Fontos

Fontos módosítások történtek a C++/WinRT Visual Studio bővítményen (VSIX) mind az 1.0.181002.2-es, majd az 1.0.190128.4-es verzióban. A módosítások részleteiről, valamint arról, hogy ezek hogyan érintik a meglévő projekteket, lásd: A C++/WinRT Visual Studio-támogatása és A VSIX-bővítmény korábbi verziói.

Elkülönítés Windows SDK-fejlécfájloktól

Ez potenciálisan kompatibilitástörő változás lehet a kódod számára.

A fordításhoz a C++/WinRT már nem függ a Windows SDK fejlécfájljaitól. A C futásidejű kódtár (CRT) és a C++ Standard sablontár (STL) fejlécfájljai szintén nem tartalmaznak Windows SDK-fejléceket. Ez javítja a szabványoknak való megfelelőséget, elkerüli a véletlen függőségeket, és jelentősen csökkenti azoknak a makróknak a számát, amelyekkel szemben védelemre van szüksége.

Ez a függetlenség azt jelenti, hogy a C++/WinRT mostantól hordozhatóbb és szabványnak megfelelőbb, és tovább fejleszti annak lehetőségét, hogy több fordítóból és platformfüggetlen könyvtárból váljon. Ez azt is jelenti, hogy a makrók nincsenek hátrányos hatással a C++/WinRT fejlécekre.

Ha korábban a C++/WinRT-re bízta, hogy beillessze a Windows-fejléceket a projektjébe, akkor mostantól önnek kell ezeket beillesztenie. Mindenesetre mindig bevált gyakorlat explicit módon felvenni azokat a fejlécfájlokat, amelyekre támaszkodik, és nem egy másik könyvtárra bízni, hogy az Ön helyett foglalja be őket.

Jelenleg a Windows SDK-fejlécfájl elkülönítésének egyetlen kivétele a belső elemek és a numerikus elemek. Az utolsó fennmaradó függőségekkel kapcsolatban nincsenek ismert problémák.

A projektben szükség esetén újra engedélyezheti a Windows SDK-fejlécekkel való interopálást. Előfordulhat például, hogy egy COM-felületet szeretne implementálni (az IUnknownben gyökerezik). Ebben a példában vegye fel a(z) unknwn.h elemet, mielőtt bármilyen C++/WinRT fejlécet felvenne. Ennek hatására a C++/WinRT alapkönyvtár lehetővé teszi a különböző horgok használatát a klasszikus COM-felületek támogatásához. Kódpéldát lásd: COM-összetevők írása C++/WinRT használatával. Hasonlóképpen, explicit módon tartalmazzon minden más Windows SDK-fejlécet, amely deklarálja a meghívni kívánt típusokat és/vagy függvényeket.

Hogyan irányíthatja át a C++/WinRT-projektjét a Windows SDK egy újabb verziójára

A projekt újraépítésének módszere, amely valószínűleg a legkevesebb fordító- és linkerproblémát eredményezi, szintén a leginkább munkaigényes. Ez a módszer magában foglalja egy új projekt létrehozását (a választott Windows SDK-verziót célozza), majd a fájlokat átmásolja az új projektbe a régiből. A régi .vcxproj- és .vcxproj.filters-fájloknak lesznek olyan részei, amelyeket egyszerűen átmásolhat, így nem kell a fájlokat a Visual Studióban hozzáadnia.

Azonban a projekt célplatformjának módosítására két másik lehetőség is van a Visual Studio-ban.

  • Lépjen az Általános>Windows SDK-verzió projekttulajdonságra, és válassza az Összes konfiguráció és minden platform lehetőséget. Állítsa Windows SDK-verziót a megcélzni kívánt verzióra.
  • A Megoldáskezelő kattintson a jobb gombbal a projektcsomópontra, kattintson a Projektek újraépítése elemre, válassza ki a megcélzott verzió(ka)t, majd kattintson az OK gombra.

Ha a két módszer valamelyikének használata után fordító- vagy linkelőhibát tapasztal, próbálja meg megtisztítani a megoldást (aTiszta megoldás> és/vagy az összes ideiglenes mappa és fájl manuális törlése) a buildelés előtt.

Ha a C++ fordító a "C2039: "IUnknown" hibát állítja elő: nem tagja a "globális névtérnek", akkor adja hozzá #include <unknwn.h> a pch.h fájl elejéhez (mielőtt c++/WinRT-fejléceket használna).

Előfordulhat, hogy ezt követően is hozzá kell adnia #include <hstring.h> .

Ha a C++ linker a következő hibaüzenetet adja: "error LNK2019: unresolved external symbol _WINRT_CanUnloadNow@0 referenced in function _VSDesignerCanUnloadNow@0", akkor ezt úgy oldhatja meg, hogy hozzáadja a #define _VSDESIGNER_DONT_LOAD_AS_DLL elemet a(z) pch.h fájlhoz.