Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Po vydání dalších verzí C++/WinRT toto téma popisuje, co je nového a co se změnilo.
Souhrn nedávných vylepšení a přidání k březnu 2020
Až 23% kratší časy sestavení
Týmy kompilátoru C++/WinRT a C++ spolupracovaly na všem možném zkrácení doby sestavení. Provedli jsme analýzu kompilátoru, abychom zjistili, jak je možné restrukturalizovat interní funkce jazyka C++/WinRT, aby kompilátor jazyka C++ eliminoval režijní náklady na kompilaci a také jak lze vylepšit samotný kompilátor jazyka C++, aby zvládl knihovnu C++/WinRT. C++/WinRT je optimalizovaný pro kompilátor; a kompilátor byl optimalizován pro C++/WinRT.
Podívejme se například na nejhorší scénář vytvoření předkompilované hlavičky (PCH), která obsahuje každou hlavičku oboru názvů projekce C++/WinRT.
| Version | Velikost PCH (bajty) | Čas (s) |
|---|---|---|
| C++/WinRT od července s Visual C++ 16.3 | 3,004,104,632 | 31 |
| verze 2.0.200316.3 C++/WinRT pro Visual C++ 16.5 | 2,393,515,336 | 24 |
20% zmenšení velikosti a 23% zkrácení doby sestavení.
Vylepšená podpora nástroje MSBuild
Hodně práce jsme investovali do vylepšení podpory nástroje MSBuild pro velký výběr různých scénářů.
Ještě rychlejší ukládání do tovární mezipaměti
Vylepšili jsme vkládání mezipaměti továrny, abychom zlepšili vložené horké cesty, což vede k rychlejšímu spuštění.
Toto vylepšení nemá vliv na velikost kódu — jak je popsáno níže v části Optimized EH code-gen, pokud vaše aplikace ve velké míře využívá zpracování výjimek v C++, můžete binární soubor zmenšit pomocí volby /d2FH4, která je ve výchozím nastavení povolená v nových projektech vytvořených v aplikaci Visual Studio 2019 verze 16.3 a novějších.
Efektivnější boxování
Při použití v aplikaci XAML je winrt::box_value nyní efektivnější (viz Boxing and unboxing). Aplikace, které často používají boxing, také zaznamenají snížení velikosti kódu.
Podpora implementace rozhraní COM implementujících IInspectable
Pokud potřebujete implementovat rozhraní COM (které není Windows Runtime), které shodou okolností implementuje IInspectable, nyní to můžete udělat pomocí C++/WinRT. Viz rozhraní COM, která implementují IInspectable.
Vylepšení uzamykání modulů
Kontrola nad uzamykáním modulů teď umožňuje jak vlastní scénáře hostování, tak úplné odstranění uzamčení na úrovni modulu. Viz vylepšení zamykání modulů.
Podpora informací o chybách mimo prostředí Windows Runtime
Některá rozhraní API (dokonce i některá rozhraní API systému prostředí Windows Runtime) hlásí chyby, aniž by používala rozhraní API systému prostředí Windows Runtime určená k předávání informací o původu chyby. V takových případech nyní C++/WinRT používá jako náhradní řešení informace o chybách COM. Informace o chybách jiných než WinRT najdete v tématu podpora C++/WinRT.
Povolení podpory modulů C++
Podpora modulu C++ je zpět, ale pouze v experimentální podobě. Tato funkce ještě není v kompilátoru jazyka C++ dokončená.
Efektivnější obnovení korutin
Korutiny C++/WinRT už mají dobrý výkon, ale nadále hledáme způsoby, jak je dále zlepšit. Viz Zlepšení škálovatelnosti korutinové resumpce.
Nové asynchronní pomocné rutiny when_all a when_any
Pomocná funkce when_all vytvoří objekt IAsyncAction , který se dokončí po dokončení všech zadaných awaitables. Pomocná rutina when_any vytvoří akci IAsyncAction , která se dokončí po dokončení některého ze zadaných awaitables.
Viz Přidat asynchronní pomocnou funkci when_any a Přidat asynchronní pomocnou funkci when_all.
Další optimalizace a doplňky
Kromě toho bylo zavedeno mnoho oprav chyb a dílčích optimalizací a doplňků, včetně různých vylepšení pro zjednodušení ladění a optimalizace interních a výchozích implementací. Úplný seznam najdete na tomto odkazu: https://github.com/microsoft/xlang/pulls?q=is%3Apr+is%3Aclosed.
Novinky a změny v C++/WinRT 2.0
Další informace o rozšíření sady Visual Studio pro C++/WinRT (VSIX), balíčku NuGet Microsoft.Windows.CppWinRT a nástroji cppwinrt.exe — včetně informací o tom, jak je získat a nainstalovat — najdete v tématu Podpora sady Visual Studio pro C++/WinRT, XAML, rozšíření VSIX a balíček NuGet.
Změny rozšíření C++/WinRT Visual Studio (VSIX) pro verzi 2.0
- Vizualizér ladění nyní podporuje Visual Studio 2019 a nadále podporuje Visual Studio 2017.
- Provedli jsme řadu oprav chyb.
Změny v balíčku NuGet Microsoft.Windows.CppWinRT pro verzi 2.0
- Nástroj
cppwinrt.exeje nyní součástí balíčku NuGet Microsoft.Windows.CppWinRT a na vyžádání generuje pro každý projekt hlavičkové soubory projekce platformy.cppwinrt.exeNástroj proto už nezávisí na sadě Windows SDK (i když se nástroj stále dodává se sadou SDK z důvodů kompatibility). -
cppwinrt.exenyní generuje hlavičkové soubory projekce v každé mezilehlé složce specifické pro platformu nebo konfiguraci ($IntDir), aby se umožnila paralelní sestavení. - Podpora sestavení C++/WinRT (props/targets) je teď plně zdokumentovaná, pokud chcete soubory projektu přizpůsobit ručně. Viz soubor readme balíčku NuGet Microsoft.Windows.CppWinRT.
- Provedli jsme řadu oprav chyb.
Změny C++/WinRT pro verzi 2.0
Otevřený zdrojový kód
Nástroj cppwinrt.exe vezme soubor metadat prostředí Windows Runtime (.winmd) a vygeneruje z něj standardní knihovnu jazyka C++ založenou na hlavičce, která podporuje rozhraní API popsaná v metadatech. Tímto způsobem můžete tato rozhraní API využívat z kódu C++/WinRT.
Tento nástroj je nyní zcela open source projekt dostupný na GitHub. Navštivte Microsoft/cppwinrt.
Knihovny xlang
Zcela přenosná knihovna jen pro hlavičky (pro analýzu formátu metadat ECMA-335 používaného prostředí Windows Runtime) tvoří základ všech nástrojů prostředí Windows Runtime a xlang, které se budou dále používat. Za zmínku stojí, že jsme také nástroj cppwinrt.exe přepsali od základů pomocí knihoven xlang. To poskytuje mnohem přesnější dotazy na metadata a řeší několik dlouhodobých problémů s projekcí jazyka C++/WinRT.
Méně závislostí
Vzhledem ke čtečce cppwinrt.exe metadat xlang má samotný nástroj méně závislostí. Díky tomu je mnohem flexibilnější i využitelná ve více scénářích – zejména v omezených prostředích sestavení. Je pozoruhodné, že už nespoléhá na RoMetadata.dll.
Toto jsou závislosti pro cppwinrt.exe 2.0.
- ADVAPI32.dll
- KERNEL32.dll
- SHLWAPI.dll
- XmlLite.dll
Všechny tyto knihovny DLL jsou k dispozici nejen na Windows 10, ale až do Windows 7, a dokonce i Windows Vista. Pokud chcete, může váš starý buildový server, na kterém běží Windows 7, spustitcppwinrt.exe, aby pro váš projekt vygeneroval hlavičky C++. S trochou práce můžete dokonce spustit C++/WinRT na Windows 7, pokud vás to zajímá.
Porovnejte výše uvedený seznam s těmito závislostmi, které má cppwinrt.exe 1.0.
- 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
Atribut prostředí Windows Runtime noexcept
prostředí Windows Runtime má nový [noexcept] atribut, který můžete použít k dekoraci metod a vlastností v MIDL 3.0. Přítomnost atributu signalizuje podpůrným nástrojům, že vaše implementace nevyvolá výjimku (ani nevrací chybový kód HRESULT). To umožňuje projekcím jazyka optimalizovat generování kódu tím, že zabrání režii zpracování výjimek, která je nutná pro podporu volání binárního rozhraní aplikace (ABI), která mohou potenciálně selhat.
C++/WinRT toho využívá vytvářením implementací jazyka C++ noexcept pro využívání i vytváření kódu. Pokud máte metody nebo vlastnosti rozhraní API, které jsou bez selhání a máte obavy o velikost kódu, můžete tento atribut prozkoumat.
Optimalizované generování kódu
C++/WinRT teď generuje ještě efektivnější zdrojový kód C++ (na pozadí), aby kompilátor jazyka C++ mohl vytvořit nejmenší a nejúčinnější binární kód, který je možný. Řada vylepšení je zaměřená na snížení nákladů na zpracování výjimek tím, že se vyhnete zbytečným informacím o uvolnění. Binární soubory, které používají velké množství kódu C++/WinRT, uvidí přibližně 4% zmenšení velikosti kódu. Kód je také efektivnější (běží rychleji) z důvodu sníženého počtu instrukcí.
Tato vylepšení využívají také novou funkci spolupráce, která je pro vás dostupná. Všechny typy C++/WinRT, které jsou vlastníky prostředků, teď obsahují konstruktor pro převzetí vlastnictví přímo, aby se zabránilo předchozímu dvoustupňovému přístupu.
ABI::Windows::Foundation::IStringable* raw = ...
IStringable projected(raw, take_ownership_from_abi);
printf("%ls\n", projected.ToString().c_str());
Optimalizované generování kódu pro zpracování výjimek (EH)
Tato změna doplňuje práci, kterou provedl optimalizátor Microsoft C++, aby se snížily náklady na zpracování výjimek. Pokud v kódu používáte binární rozhraní aplikací (ABI) (například COM), budete sledovat velké množství kódu, který sleduje tento vzor.
int32_t Function() noexcept
{
try
{
// code here constitutes unique value.
}
catch (...)
{
// code here is always duplicated.
}
}
C++/WinRT sám generuje tento vzor pro každé implementované rozhraní API. Díky tisícům funkcí rozhraní API může být jakákoli optimalizace důležitá. V minulosti optimalizátor nerozpoznal, že všechny bloky catch jsou identické, takže duplikuje spoustu kódu kolem každého ABI (což pak přispělo k přesvědčení, že použití výjimek v systémovém kódu vytváří velké binární soubory). Od verze Visual Studio 2019 však kompilátor jazyka C++ slučuje všechny tyto catch funclety a ukládá pouze ty, které jsou jedinečné. Výsledkem je další a celkově 18% zmenšení velikosti kódu pro binární soubory, které se na tento model silně spoléhají. Kód EH je teď nejen efektivnější než použití návratových kódů, ale také obava o větší binární soubory je teď věcí minulosti.
Vylepšení přírůstkového sestavení
Nástroj cppwinrt.exe teď porovná výstup vygenerovaného hlavičkového nebo zdrojového souboru s obsahem jakéhokoli existujícího souboru na disku a zapíše ho jenom v případě, že se soubor ve skutečnosti změnil. To šetří značnou dobu s vstupně-výstupními operacemi disku a zajišťuje, že soubory nejsou považovány za "špinavé" kompilátorem jazyka C++. Výsledkem je, že se v mnoha případech vyhnete nebo snížíte rekompilace.
Všechna obecná rozhraní jsou nyní generována.
Vzhledem ke čtečce metadat xlang teď C++/WinRT generuje všechna parametrizovaná nebo obecná rozhraní z metadat. Rozhraní jako Windows::Foundation::Collections::IVector<T> se nyní generují z metadat, místo aby byla ručně psána v winrt/base.h. Výsledkem je, že velikost winrt/base.h se snížila na polovinu a optimalizace se vygenerují přímo do kódu (což bylo složité udělat s ručním přístupem).
Důležité
Rozhraní, jako je příklad uvedený nyní, se zobrazují v příslušných hlavičkách oboru názvů, nikoli v winrt/base.h. Pokud jste to tedy ještě neudělali, budete muset vložit příslušný hlavičkový soubor oboru názvů, abyste mohli rozhraní použít.
Optimalizace komponent
Tato aktualizace přidává podporu pro několik dalších optimalizací výslovného souhlasu pro C++/WinRT, které jsou popsány v následujících částech. Protože tyto optimalizace představují nekompatibilní změny (kvůli nimž možná budete muset provést drobné úpravy), budete je muset zapnout explicitně. V Visual Studio nastavte vlastnost projektu Common Properties>C++/WinRT>Optimized na Ano. To má vliv na přidání <CppWinRTOptimized>true</CppWinRTOptimized> do souboru projektu. A má stejný účinek jako přidání -opt[imize] přepínače při vyvolání cppwinrt.exe z příkazového řádku.
Nový projekt (vytvořený ze šablony projektu) bude ve výchozím nastavení používat -opt.
Jednotný stavební a přímý přístup k implementaci
Tyto dvě optimalizace umožňují vaší komponentě přímý přístup k vlastním typům implementace, i když používají pouze projektované typy. Není nutné používat make, make_self ani get_self , pokud chcete jednoduše použít veřejný povrch rozhraní API. Vaše volání se zkompilují na přímá volání implementace a ta mohou být dokonce zcela inlineovaná.
Další informace a příklady kódu najdete v tématu Vyjádření souhlasu s jednotným sestavováním a přímým přístupem k implementaci.
Továrny s vymazaným typem
Tato optimalizace zabraňuje závislostem #include module.g.cpp tak, aby se nemusely rekompilovat pokaždé, když dojde ke změně jakékoli třídy implementace. Výsledkem je lepší výkon procesu sestavení.
Chytřejší a efektivnější module.g.cpp pro velké projekty s více knihovnami
Soubor module.g.cpp nyní také obsahuje dvě další komponovatelné pomocné funkce pojmenované winrt_can_unload_now a winrt_get_activation_factory. Tyto projekty byly navrženy pro větší projekty, kde se knihovna DLL skládá z řady libů, z nichž každá má vlastní třídy modulu runtime. V takovém případě musíte ručně spojit dll DllGetActivationFactory a DllCanUnloadNow. Tyto pomocné funkce vám to výrazně usnadňují tím, že zabraňují falešným chybám při vytváření. Příznak cppwinrt.exe nástroje -lib lze také použít k tomu, aby každá jednotlivá lib měla vlastní preambuli (nikoli winrt_xxx), aby funkce jednotlivých libů mohly být pojmenovány jednotlivě, a proto jednoznačně sloučeny.
Podpora coroutine
Podpora Coroutine je zahrnuta automaticky. Dříve se podpora nacházela na více místech, což bylo příliš omezující. A pak byl pro v2.0 dočasně nutný hlavičkový soubor winrt/coroutine.h, ale to už není nutné. Vzhledem k tomu, že se asynchronní rozhraní prostředí Windows Runtime nyní generují, místo aby se psala ručně, nacházejí se nyní v winrt/Windows.Foundation.h. Kromě toho, že je snáze udržovatelný a podporovatelný, to znamená, že pomocné funkce pro korutiny, jako jsou resume_foreground, už nemusí být připojovány na konec hlavičkového souboru konkrétního oboru názvů. Místo toho mohou přirozeněji zahrnovat své závislosti. To dále umožňuje, aby resume_foreground podporoval nejen obnovení na daném Windows::UI::Core::CoreDispatcher, ale nově také obnovení na daném Windows::System::DispatcherQueue. Dříve bylo možné podporovat pouze jeden; ale ne obojí, protože definice se může nacházet pouze v jednom oboru názvů.
Tady je příklad podpory 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);
}
Pomocné funkce pro korutiny jsou nyní také opatřeny dekorátorem [[nodiscard]], což zlepšuje jejich použitelnost. Pokud je zapomenete (nebo si neuvědomíte, že je to nutné) co_await, aby fungovaly, pak kvůli [[nodiscard]] takové chyby nyní vyvolají varování kompilátoru.
Pomoc s diagnostikou přímého přidělení (zásobníku)
Vzhledem k tomu, že názvy projektované a implementační třídy jsou (ve výchozím nastavení) stejné a liší se pouze jmenným prostorem, je možné si je navzájem splést a omylem vytvořit implementační objekt na zásobníku namísto použití sady pomocných funkcí make. V některých případech to může být obtížné diagnostikovat, protože objekt může být zničen, zatímco nevyřízené odkazy jsou stále v letu. Assert to nyní zachytí v ladicích sestaveních. I když tvrzení nerozpozná alokaci na zásobníku uvnitř korutiny, je přesto užitečné k odhalení většiny takových chyb.
Další informace najdete v tématu Diagnostika přímých přidělení.
Vylepšené pomocné funkce pro zachytávání a variadické delegáty
Tato aktualizace odstraňuje omezení pomocných funkcí pro zachytávání a nově podporuje i projektované typy. To se čas od času stává u rozhraní API pro interoperabilitu s prostředí Windows Runtime, když vracejí promítnutý typ.
Tato aktualizace také přidává podporu pro get_strong a get_weak při vytváření delegáta s proměnným počtem argumentů (mimo prostředí Windows Runtime).
Podpora odloženého zničení a bezpečného QI při zničení
Není neobvyklé, že se v destruktoru objektu běhové třídy volá metoda, která dočasně zvýší počet referencí. Když počet odkazů klesne zpět na nulu, objekt je zničen podruhé. V aplikaci XAML možná budete muset v destruktoru provést operaci QueryInterface (QI), abyste mohli zavolat nějakou implementaci pro vyčištění výše nebo níže v hierarchii. Ale počet odkazů objektu již dosáhl nuly, takže QI představuje také odraz počtu odkazů.
Tato aktualizace přidává podporu pro potlačení kolísání počtu referencí, takže jakmile klesne na nulu, už jej nelze znovu navýšit, a zároveň vám stále umožňuje provádět QI pro libovolné dočasné objekty, které během destrukce potřebujete. Tento postup je v některých aplikacích nebo ovládacích prvcích XAML nevyhnutelný a C++/WinRT si s ním nyní poradí.
Zničení můžete odložit poskytnutím statické final_release funkce typu implementace. Poslední zbývající ukazatel na objekt, ve formě std::unique_ptr, se předá vašemu final_release. Pak se můžete rozhodnout přesunout vlastnictví tohoto ukazatele na jiný kontext. Je bezpečné provést QI na ukazateli, aniž by došlo k dvojité destrukci. Ale výsledná změna počtu referencí musí být v okamžiku, kdy objekt zničíte, nulová.
Návratovou hodnotou final_release může být voidobjekt asynchronní operace, například IAsyncAction nebo 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.
}
};
V následujícím příkladu se po posledním uvolnění MainPage zavolá final_release. Tato funkce stráví pět sekund čekáním (ve fondu vláken) a pak se obnoví pomocí dispečeru stránky (který vyžaduje, aby funkce QI/AddRef/Release fungovala). Potom vyčistí prostředek v daném vlákně uživatelského rozhraní. A nakonec vynuluje unique_ptr, čímž se skutečně zavolá destruktor MainPage. I v tom destruktoru je volána DataContext , která vyžaduje QI pro IFrameworkElement.
Nemusíte implementovat final_release jako korutinu. Ale to funguje a je velmi jednoduché přesunout zničení do jiného vlákna, což je to, co se děje v tomto příkladu.
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;
}
};
Další informace najdete v tématu Odložené zničení.
Vylepšená podpora dědičnosti z jednoho rozhraní ve stylu COM
C++/WinRT se používá nejen pro programování pro prostředí Windows Runtime, ale také k vytváření a využívání rozhraní API pouze pro COM. Tato aktualizace umožňuje implementovat server COM, kde existuje hierarchie rozhraní. To není nutné pro prostředí Windows Runtime; ale vyžaduje se pro některé implementace modelu COM.
Správné zpracování out parametrů
Práce s parametry out může být složitá, zejména s poli systému prostředí Windows Runtime. Při této aktualizaci je C++/WinRT výrazně robustnější a odolnější vůči chybám, pokud jde o out parametry a pole, ať už tyto parametry přicházejí prostřednictvím projekce jazyka, nebo od vývojáře modelu COM, který používá nezpracované ABI a kdo dělá chybu, že neicializuje proměnné konzistentně. V obou případech teď C++/WinRT postupuje správně, pokud jde o předávání projektovaných typů do ABI (tj. nezapomene uvolnit všechny prostředky), i pokud jde o vynulování nebo vyčištění parametrů, které přicházejí přes rozhraní ABI.
Události nyní zpracovávají neplatné tokeny spolehlivě.
Implementace winrt::event nyní elegantně zpracovává případ, kdy je volána metoda remove s neplatnou hodnotou tokenu (hodnota, která není přítomna v poli).
Lokální proměnné korutiny se nyní zničí před návratem korutiny.
Tradiční způsob implementace korutinového typu může umožnit zničení místních proměnných v korutině po návratu/dokončení korutiny (nikoli před konečným pozastavením). Obnovení libovolného číšníka je nyní odloženo až do konečného pozastavení, aby se zabránilo tomuto problému a nabíhání dalších výhod.
Novinky a změny v sadě Windows SDK verze 10.0.17763.0 (Windows 10 verze 1809)
Následující tabulka obsahuje novinky a změny pro C++/WinRT v sadě Windows SDK verze 10.0.17763.0 (Windows 10 verze 1809).
| Nová nebo změněná funkce | Další informace |
|---|---|
| Změna způsobující chybu. Aby bylo možné ji zkompilovat, C++/WinRT nezávisí na hlavičkách ze sady Windows SDK. | Níže najdete informace o izolaci souborů hlaviček sady Windows SDK. |
| Formát systému projektu Visual Studio se změnil. | Podívejte se, jak změnit cílení projektu C++/WinRT na novější verzi Windows SDK níže. |
| Existují nové funkce a základní třídy, které vám pomůžou předat objekt kolekce prostředí Windows Runtime funkci nebo implementovat vlastní vlastnosti kolekce a typy kolekcí. | Viz kolekce s C++/WinRT. |
| Rozšíření značky {Binding} můžete použít s třídami modulu runtime C++/WinRT. | Další informace a příklady kódu najdete v přehledu datových vazeb. |
| Podpora zrušení korutiny umožňuje zaregistrovat zpětné volání zrušení. | Další informace a příklady kódu najdete v tématu Zrušení asynchronní operace a zpětné volání zrušení. |
| Při vytváření delegáta odkazujícího na členskou funkci můžete v okamžiku registrace obslužné rutiny vytvořit silnou nebo slabou referenci na aktuální objekt (namísto nezpracovaného ukazatele this). | Další informace a příklady kódu najdete v pododdílu Pokud používáte členskou funkci jako delegáta v oddílu Bezpečný přístup k ukazateli this pomocí delegáta pro zpracování událostí. |
| Chyby jsou opraveny tím, že Visual Studio zlepšila shodu se standardem C++. Sada nástrojů LLVM a Clang se také lépe využívá k ověření shody standardů C++/WinRT. | Už se nebudete setkávat s problémem popsaným v části Proč se můj nový projekt nezkompiluje? Používám Visual Studio 2017 (verze 15.8.0 nebo novější) a sadu SDK verze 17134 |
Další změny.
-
Změna způsobující chybu.
winrt::get_abi(winrt::hstring const&) nyní vrátí
void*místoHSTRING. Pomocístatic_cast<HSTRING>(get_abi(my_hstring));můžete získat hodnotu HSTRING. Viz Spolupráce s HSTRING ABI. -
Změna způsobující chybu.
winrt::put_abi(winrt::hstring&) nyní vrací
void**místoHSTRING*. Můžete použítreinterpret_cast<HSTRING*>(put_abi(my_hstring));k získání HSTRING*. Viz Spolupráce s HSTRING ABI. -
Změna způsobující chybu. HRESULT se nyní mapuje na winrt::hresult. Pokud potřebujete HRESULT (ke kontrole typů nebo k podpoře typových vlastností), můžete použít
static_castwinrt::hresult. Jinak se winrt::hresult převede na HRESULT, pokud před zahrnutím všech hlaviček C++/WinRT přidáteunknwn.h. -
Změna způsobující chybu. Identifikátor GUID je nyní promítaný jako winrt::guid. Pro rozhraní API, která implementujete, musíte pro parametry GUID použít winrt::guid . Jinak se winrt::guid převede na GUID, pokud zahrnete
unknwn.hpřed zahrnutím jakýchkoli hlaviček C++/WinRT. Viz Interoperabilita se strukturou GUID ABI. - Změna způsobující chybu. Konstruktor winrt::handle_type byl zpřísněn tím, že byl označen jako explicit (teď je těžší při jeho použití napsat nesprávný kód). Pokud potřebujete přiřadit surovou hodnotu popisovače, volejte místo toho funkci handle_type::attach.
-
Změna způsobující chybu. Podpisy WINRT_CanUnloadNow a WINRT_GetActivationFactory se změnily. Tyto funkce nesmíte deklarovat vůbec. Místo toho zahrňte
winrt/base.h(která je automaticky zahrnuta, pokud zahrnete všechny soubory hlaviček oboru názvů C++/WinRT Windows) pro zahrnutí deklarací těchto funkcí. - Pro strukturu winrt::clock jsou from_FILETIME/to_FILETIME zastaralé ve prospěch from_file_time/to_file_time.
- Zjednodušená rozhraní API, která očekávají parametry IBuffer . Většina rozhraní API upřednostňuje kolekce nebo pole. Ale cítili jsme, že bychom měli usnadnit volání rozhraní API, která spoléhají na IBuffer. Tato aktualizace poskytuje přímý přístup k datům za implementací IBuffer . Používá stejnou konvenci pojmenování dat jako ty, které používají kontejnery standardní knihovny C++. Tato konvence také zabraňuje kolizím s názvy metadat, které obvykle začínají velkým písmenem.
- Vylepšené generování kódu: různá vylepšení zmenšení velikosti kódu, zlepšení vkládání a optimalizace ukládání do mezipaměti továrny.
- Byla odstraněna zbytečná rekurze. Pokud je na příkazovém řádku zadána složka, nikoli konkrétní
.winmd, nástrojcppwinrt.exejiž nebude rekurzivně vyhledávat soubory.winmd. Nástrojcppwinrt.exeteď také zpracovává duplicity inteligentněji, takže je odolnější vůči chybám uživatelů a ke špatně vytvořeným.winmdsouborům. - Posílené inteligentní ukazatele Dříve se odvolání událostí nepodařilo odvolat při přiřazení nové hodnoty. To pomohlo odhalit problém, kdy třídy inteligentních ukazatelů spolehlivě nezpracovávaly vlastní přiřazení; rooted in the winrt::com_ptr struct template. winrt::com_ptr byla opravena a odvolávače událostí byly upraveny tak, aby správně pracovaly se sémantikou přesunu, takže při přiřazení dojde k revokaci.
Důležité
V rozšíření C++/WinRT Visual Studio (VSIX) byly provedeny důležité změny, a to jak ve verzi 1.0.181002.2, tak později ve verzi 1.0.190128.4. Podrobnosti o těchto změnách a o tom, jak ovlivňují vaše stávající projekty, Visual Studio podporu pro C++/WinRT a starší verze rozšíření VSIX.
Izolace od hlavičkových souborů sady Windows SDK
Toto je potenciálně zásadní změna kódu.
Pro kompilaci už C++/WinRT nezávisí na hlavičkových souborech ze sady Windows SDK. Soubory hlaviček v knihovně C runtime (CRT) a knihovně STL (Standard Template Library) jazyka C++ také neobsahují žádné hlavičky sady WINDOWS SDK. A to zlepšuje soulad se standardy, zabraňuje neúmyslným závislostem a výrazně snižuje počet maker, před nimiž se musíte chránit.
Tato nezávislost znamená, že jazyk C++/WinRT je teď přenosnější a vyhovuje standardům a dále je možné, že se stane multikompilátorem a knihovnou pro různé platformy. Také to znamená, že hlavičky C++/WinRT nejsou nepříznivě ovlivněny makry.
Pokud jste ho dříve nechali na C++/WinRT, abyste do projektu zahrnuli všechny hlavičky Windows, budete je muset zahrnout sami. V každém případě je vždy osvědčeným postupem explicitně zahrnout hlavičky, na které jste závislí, a nenechávejte je v jiné knihovně, aby je zahrnula za vás.
V současné době jsou jedinými výjimkami z izolace hlavičkových souborů sady Windows SDK intrinsics a numerika. Neexistují žádné známé problémy s těmito posledními zbývajícími závislostmi.
V projektu můžete znovu povolit interoperabilitu s hlavičkami sady Windows SDK, pokud potřebujete. Můžete například chtít implementovat rozhraní COM (root v IUnknown). V tomto příkladu uveďte unknwn.h před zahrnutím hlaviček C++/WinRT. Tím se základní knihovně C++/WinRT zpřístupní různé napojovací body pro podporu klasických rozhraní COM. Příklad kódu najdete v tématu Vytváření komponent modelu COM pomocí C++/WinRT. Podobně explicitně zahrňte všechny další hlavičky sady WINDOWS SDK, které deklarují typy nebo funkce, které chcete volat.
Postup opětovného cílení projektu C++/WinRT na novější verzi sady Windows SDK
Metoda opětovného cílení projektu, která pravděpodobně vede k nejmenšímu problému kompilátoru a linkeru, je také nejpracnější. Tato metoda zahrnuje vytvoření nového projektu (cílení na verzi sady Windows SDK podle vašeho výběru) a následné kopírování souborů do nového projektu ze starého projektu. Budou tam oddíly starých .vcxproj souborů a .vcxproj.filters souborů, které můžete jednoduše zkopírovat, abyste si uložili přidávání souborů do Visual Studio.
Existují však ještě dva další způsoby, jak v aplikaci Visual Studio změnit cílení projektu.
- Přejděte na vlastnost projektu Obecné>Windows verze sady SDK a vyberte Všechny konfigurace a všechny platformy. Nastavte Windows verzi sady SDK na verzi, na kterou chcete cílit.
- V Průzkumník řešení klepněte pravým tlačítkem myši na uzel projektu, klepněte na příkaz Projekty Retarget, zvolte verze, které chcete cílit, a potom klepněte na tlačítko OK.
Pokud po použití některé z těchto dvou metod dojde k nějakým chybám kompilátoru nebo linkeru, můžete zkusit řešení vyčistit (sestavit>čisté řešení nebo ručně odstranit všechny dočasné složky a soubory) a teprve potom se znovu pokusit sestavit.
Pokud kompilátor C++ hlásí „error C2039: 'IUnknown': is not a member of '`global namespace''“, přidejte #include <unknwn.h> na začátek souboru pch.h (před vložením jakýchkoli hlaviček C++/WinRT).
Možná budete muset #include <hstring.h> přidat i potom.
Pokud linker jazyka C++ vypíše „chyba LNK2019: nevyřešený externí symbol _WINRT_CanUnloadNow@0, na který je odkazováno ve funkci _VSDesignerCanUnloadNow@0“, můžete to vyřešit přidáním #define _VSDESIGNER_DONT_LOAD_AS_DLL do souboru pch.h.
Windows developer