Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Saat versi C++/WinRT berikutnya dirilis, topik ini menjelaskan apa yang baru, dan apa yang berubah.
Rollup perbaikan/penambahan terbaru per Maret 2020
Hingga 23% waktu build yang lebih pendek
Tim kompilator C++/WinRT dan C++ telah berkolaborasi untuk melakukan segala yang mungkin untuk mempersingkat waktu build. Kami telah menelaah secara mendalam analisis kompilator untuk mencari tahu bagaimana bagian internal C++/WinRT dapat disusun ulang guna membantu kompiler C++ menghilangkan overhead waktu kompilasi, serta bagaimana kompiler C++ itu sendiri dapat ditingkatkan agar dapat mendukung pustaka C++/WinRT dengan lebih baik. C++/WinRT telah dioptimalkan untuk pengkompilasi; dan kompilator telah dioptimalkan untuk C++/WinRT.
Mari kita ambil sebagai contoh skenario terburuk saat membuat header prakompilasi (PCH) yang berisi setiap header namespace proyeksi C++/WinRT.
| Versi | Ukuran PCH (byte) | Waktu (s) |
|---|---|---|
| C++/WinRT mulai Juli, dengan Visual C++ 16.3 | 3,004,104,632 | 31 |
| versi 2.0.200316.3 dari C++/WinRT, dengan Visual C++ 16.5 | 2,393,515,336 | 24 |
Pengurangan ukuran sebesar 20%, dan pengurangan waktu build sebesar 23%.
Dukungan MSBuild yang disempurnakan
Kami telah menginvestasikan banyak pekerjaan untuk meningkatkan dukungan MSBuild untuk berbagai pilihan skenario yang berbeda.
Cache pabrik yang lebih cepat lagi
Kami telah meningkatkan inlining pada cache factory agar hot path dapat di-inline dengan lebih baik, sehingga eksekusi menjadi lebih cepat.
Peningkatan tersebut tidak memengaruhi ukuran kode—seperti yang dijelaskan di bawah dalam pembuatan kode EH yang dioptimalkan, jika aplikasi Anda sangat bergantung pada penanganan pengecualian C++, Anda dapat mengurangi ukuran biner Anda dengan menggunakan opsi /d2FH4, yang diaktifkan secara default pada proyek baru yang dibuat dengan Visual Studio 2019 16.3 dan versi yang lebih baru.
Tinju yang lebih efisien
Ketika digunakan dalam aplikasi XAML, winrt::box_value sekarang lebih efisien (lihat boxing dan unboxing). Aplikasi yang banyak melakukan boxing juga akan mengalami pengurangan ukuran kode.
Dukungan untuk menerapkan antarmuka COM yang mengimplementasikan IInspectable
Jika Anda perlu menerapkan antarmuka COM (non-Windows-Runtime) yang kebetulan mengimplementasikan IInspectable, maka Anda sekarang dapat melakukannya dengan C++/WinRT. Lihat antarmuka COM yang mengimplementasikan IInspectable.
Peningkatan penguncian modul
Kontrol atas penguncian modul sekarang memungkinkan baik skenario hosting khusus maupun penghapusan sepenuhnya penguncian di tingkat modul. Lihat Peningkatan penguncian modul.
Dukungan untuk informasi kesalahan non-Windows-Runtime
Beberapa API (bahkan beberapa API Windows Runtime) melaporkan kesalahan tanpa menggunakan API asal kesalahan Windows Runtime. Dalam kasus seperti itu, C++/WinRT sekarang kembali menggunakan info kesalahan COM. Lihat dukungan C++/WinRT untuk informasi kesalahan non-WinRT.
Mengaktifkan dukungan modul C++
Dukungan modul C++ kembali, tetapi hanya dalam bentuk eksperimental. Fitur ini belum lengkap di pengkompilasi C++.
Penerbitan ulang koroutine yang lebih efisien
Koroutin C++/WinRT sudah berkinerja baik, tetapi kami terus mencari cara untuk meningkatkannya. Lihat Meningkatkan skalabilitas penerbitan ulang koroutine.
Pembantu asinkron when_all dan when_any baru
Fungsi pembantu when_all membuat objek IAsyncAction yang akan selesai ketika semua awaitable yang diberikan telah selesai. Fungsi pembantu when_any membuat IAsyncAction yang selesai ketika salah satu awaitable yang diberikan telah selesai.
Lihat Tambahkan fungsi pembantu asinkron when_any dan Tambahkan fungsi pembantu asinkron when_all.
Pengoptimalan dan penambahan lainnya
Selain itu, banyak perbaikan bug, pengoptimalan minor, serta penambahan kecil telah dihadirkan, termasuk berbagai peningkatan untuk menyederhanakan debugging dan mengoptimalkan komponen internal serta implementasi bawaan. Ikuti tautan ini untuk daftar lengkap: https://github.com/microsoft/xlang/pulls?q=is%3Apr+is%3Aclosed.
Berita, dan perubahan, di C++/WinRT 2.0
Untuk informasi selengkapnya tentang C++/WinRT Visual Studio Extension (VSIX), Microsoft.Windows. Paket CppWinRT NuGet, dan alat—cppwinrt.exetermasuk cara memperoleh dan menginstalnya—lihat dukungan Visual Studio untuk C++/WinRT, XAML, ekstensi VSIX, dan paket NuGet.
Perubahan pada C++/WinRT Visual Studio Extension (VSIX) untuk versi 2.0
- Visualizer debug sekarang mendukung Visual Studio 2019; serta terus mendukung Visual Studio 2017.
- Banyak perbaikan bug telah dibuat.
Perubahan pada paket NuGet Microsoft.Windows.CppWinRT di versi 2.0
- Alat
cppwinrt.exekini disertakan dalam paket NuGet Microsoft.Windows.CppWinRT, dan alat ini menghasilkan header proyeksi platform untuk setiap proyek sesuai permintaan. Akibatnya, alat inicppwinrt.exetidak lagi tergantung pada Windows SDK (meskipun, alat ini masih dikirim dengan SDK karena alasan kompatibilitas). -
cppwinrt.exesekarang menghasilkan header proyeksi di dalam setiap folder perantara ($IntDir) yang khusus untuk platform/konfigurasi agar memungkinkan build paralel. - Dukungan build C++/WinRT (props/targets) kini telah didokumentasikan sepenuhnya, jika Anda ingin menyesuaikan file proyek secara manual. Lihat readme paket NuGet Microsoft.Windows.CppWinRT.
- Banyak perbaikan bug telah dibuat.
Perubahan pada C++/WinRT untuk versi 2.0
Sumber terbuka
Alat cppwinrt.exe ini mengambil file metadata Windows Runtime (.winmd), dan darinya menghasilkan pustaka C++ standar berbasis berkas header yang memproyeksikan API yang dijelaskan dalam metadata. Dengan demikian, Anda dapat menggunakan API tersebut dari kode C++/WinRT Anda.
Alat ini sekarang merupakan proyek yang sepenuhnya sumber terbuka, tersedia di GitHub. Kunjungi Microsoft/cppwinrt.
pustaka xlang
Pustaka header-only yang sepenuhnya portabel (untuk mengurai format metadata ECMA-335 yang digunakan oleh Windows Runtime) menjadi dasar bagi semua perkakas Windows Runtime dan xlang ke depannya. Yang perlu dicatat, kami juga menulis ulang alat cppwinrt.exe dari awal menggunakan pustaka xlang. Ini menyediakan kueri metadata yang jauh lebih akurat, memecahkan beberapa masalah lama dengan proyeksi bahasa C++/WinRT.
Lebih sedikit dependensi
Berkat pembaca metadata xlang, alat cppwinrt.exe itu sendiri memiliki lebih sedikit ketergantungan. Hal ini membuatnya jauh lebih fleksibel, serta dapat digunakan dalam lebih banyak skenario—terutama di lingkungan build yang dibatasi. Terutama, itu tidak lagi bergantung pada RoMetadata.dll.
Ini adalah dependensi untuk cppwinrt.exe 2.0.
- ADVAPI32.dll
- KERNEL32.dll
- SHLWAPI.dll
- XmlLite.dll
Semua DLL tersebut tersedia tidak hanya di Windows 10, tetapi sampai ke Windows 7, dan bahkan Windows Vista. Jika Anda menginginkannya, server build lama yang menjalankan Windows 7 sekarang dapat berjalan cppwinrt.exe untuk menghasilkan header C++ untuk proyek Anda. Dengan sedikit pekerjaan, Anda bahkan dapat menjalankan C++/WinRT di Windows 7, jika itu menarik minat Anda.
Bandingkan daftar di atas dengan dependensi berikut, yang dimiliki 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 Windows Runtime noexcept
Windows Runtime memiliki atribut baru[noexcept], yang dapat Anda gunakan untuk menghias metode dan properti Anda di MIDL 3.0. Kehadiran atribut menunjukkan kepada alat pendukung bahwa implementasi Anda tidak melemparkan pengecualian (atau mengembalikan HRESULT yang gagal). Ini memungkinkan proyeksi bahasa untuk mengoptimalkan pembuatan kode dengan menghindari overhead penanganan pengecualian yang diperlukan untuk mendukung panggilan antarmuka biner aplikasi (ABI) yang berpotensi gagal.
C++/WinRT memanfaatkan hal ini dengan menghasilkan implementasi C++ noexcept dari kode konsumen dan kode authoring. Jika Anda memiliki metode API atau properti yang bebas kegagalan, dan Anda khawatir tentang ukuran kode, maka Anda dapat menyelidiki atribut ini.
Pembuatan kode yang dioptimalkan
C++/WinRT sekarang menghasilkan kode sumber C++ yang lebih efisien (di belakang layar) sehingga pengkompilasi C++ dapat menghasilkan kode biner terkecil dan paling efisien yang mungkin. Banyak dari peningkatan tersebut ditujukan untuk mengurangi biaya penanganan eksepsi dengan menghindari informasi unwind yang tidak diperlukan. Biner yang menggunakan kode C++/WinRT dalam jumlah besar akan mengalami pengurangan ukuran kode sekitar 4%. Kode ini juga lebih efisien (berjalan lebih cepat) karena jumlah instruksi yang berkurang.
Peningkatan ini bergantung pada fitur interop baru yang juga tersedia bagi Anda. Semua jenis C++/WinRT yang merupakan pemilik sumber daya sekarang menyertakan konstruktor untuk mengambil kepemilikan secara langsung, menghindari pendekatan dua langkah sebelumnya.
ABI::Windows::Foundation::IStringable* raw = ...
IStringable projected(raw, take_ownership_from_abi);
printf("%ls\n", projected.ToString().c_str());
Pembuatan kode penanganan pengecualian (EH) yang dioptimalkan
Perubahan ini melengkapi pekerjaan yang telah dilakukan oleh tim pengoptimal C++ Microsoft untuk mengurangi biaya penanganan pengecualian. Jika Anda menggunakan antarmuka biner aplikasi (ARI) (seperti COM) sangat dalam kode Anda, maka Anda akan mengamati banyak kode mengikuti pola ini.
int32_t Function() noexcept
{
try
{
// code here constitutes unique value.
}
catch (...)
{
// code here is always duplicated.
}
}
C++/WinRT sendiri menghasilkan pola ini untuk setiap API yang diimplementasikan. Dengan ribuan fungsi API, pengoptimalan apa pun di sini bisa signifikan. Di masa lalu, pengoptimal tidak akan mendeteksi bahwa blok tangkapan tersebut semuanya identik, sehingga menduplikasi banyak kode di sekitar setiap ABI (yang pada gilirannya berkontribusi pada keyakinan bahwa menggunakan pengecualian dalam kode sistem menghasilkan biner besar). Namun, mulai Visual Studio 2019 dan seterusnya, kompilator C++ menggabungkan semua funclet catch tersebut dan hanya menyimpan funclet yang unik. Hasilnya, ukuran kode pada biner yang sangat bergantung pada pola ini berkurang lebih lanjut, dengan total pengurangan keseluruhan sebesar 18%. Kode EH kini tidak hanya lebih efisien daripada penggunaan kode pengembalian, tetapi kekhawatiran akan biner berukuran lebih besar juga tidak lagi menjadi masalah.
Peningkatan pada build inkremental
Alat cppwinrt.exe ini sekarang membandingkan output file header/sumber yang dihasilkan dengan isi file apa pun yang sudah ada di disk, dan hanya menulis file tersebut jika file itu memang telah berubah. Ini menghemat banyak waktu dengan I/O disk, dan memastikan bahwa file tidak dianggap "kotor" oleh pengkompilasi C++. Hasilnya adalah kompilasi ulang dihindari, atau dikurangi, dalam banyak kasus.
Antarmuka generik kini semuanya dibuat secara otomatis
Karena pembaca metadata xlang, C++/WinRT sekarang menghasilkan semua antarmuka berparameter, atau umum dari metadata. Antarmuka seperti Windows::Foundation::Collections::IVector<T> kini dihasilkan dari metadata, bukan lagi ditulis secara manual di winrt/base.h. Hasilnya, ukuran winrt/base.h berkurang setengahnya, dan pengoptimalan langsung dihasilkan di dalam kode (yang sulit dilakukan dengan pendekatan manual).
Important
Antarmuka seperti contoh yang diberikan sekarang muncul di header namespace masing-masing, bukan di winrt/base.h. Jadi, jika Anda belum melakukannya, Anda harus menyertakan header namespace yang sesuai untuk menggunakan antarmuka.
Pengoptimalan komponen
Pembaruan ini menambahkan dukungan untuk beberapa pengoptimalan keikutsertaan tambahan untuk C++/WinRT, yang dijelaskan di bagian di bawah ini. Karena pengoptimalan ini melanggar perubahan (yang mungkin perlu Anda buat perubahan kecil pada dukungan), Anda harus mengaktifkannya secara eksplisit. Di Visual Studio, atur properti proyek Properti> UmumC++/WinRT>Dioptimalkan ke Ya. Itu memiliki efek menambahkan <CppWinRTOptimized>true</CppWinRTOptimized> ke file proyek Anda. Dan ini memiliki efek yang sama seperti menambahkan sakelar -opt[imize] saat memanggil cppwinrt.exe dari baris perintah.
Proyek baru (dari templat proyek) akan digunakan -opt secara default.
Konstruksi seragam, dan akses implementasi langsung
Kedua pengoptimalan ini memungkinkan akses langsung komponen Anda ke jenis implementasinya sendiri, bahkan ketika hanya menggunakan jenis yang diproyeksikan. Tidak perlu menggunakan make, make_self, atau get_self jika Anda hanya ingin menggunakan permukaan API publik. Panggilan Anda akan dikompilasi menjadi pemanggilan langsung ke implementasinya, dan pemanggilan itu bahkan mungkin sepenuhnya di-inline-kan.
Untuk informasi selengkapnya, dan contoh kode, lihat Ikut serta dalam konstruksi seragam, dan akses implementasi langsung.
Pabrik yang dihapus jenis
Pengoptimalan ini menghindari dependensi #include dalam module.g.cpp sehingga module.g.cpp tidak perlu dikompilasi ulang setiap kali salah satu kelas implementasi berubah. Hasilnya adalah peningkatan performa proses build.
Lebih cerdas dan efisien module.g.cpp untuk proyek besar dengan beberapa libs
File module.g.cpp sekarang juga berisi dua pembantu tambahan yang dapat disusun, bernama winrt_can_unload_now, dan winrt_get_activation_factory. Ini telah dirancang untuk proyek yang lebih besar di mana DLL terdiri dari sejumlah libs, masing-masing dengan kelas runtime sendiri. Dalam situasi tersebut, Anda perlu merangkai DllGetActivationFactory dan DllCanUnloadNow milik DLL tersebut secara manual. Alat bantu ini sangat memudahkan Anda untuk melakukannya dengan menghindari kesalahan asal yang keliru. Flag cppwinrt.exe pada alat -lib juga dapat digunakan untuk memberi setiap lib preambelnya sendiri (bukan winrt_xxx), sehingga fungsi dari tiap lib dapat diberi nama secara terpisah dan dengan demikian digabungkan tanpa ambiguitas.
Dukungan korutin
Dukungan Coroutine disertakan secara otomatis. Sebelumnya, dukungan berada di beberapa tempat, yang kami rasa terlalu membatasi. Lalu, untuk sementara pada v2.0, berkas header winrt/coroutine.h diperlukan, tetapi itu tidak diperlukan lagi. Karena antarmuka asinkron Windows Runtime sekarang dibuat secara otomatis, bukan ditulis secara manual, antarmuka tersebut kini berada di winrt/Windows.Foundation.h. Selain lebih mudah dipelihara dan didukung, artinya fungsi pembantu coroutine seperti resume_foreground tidak lagi harus ditambahkan begitu saja di akhir header namespace tertentu. Sebaliknya, mereka dapat menyertakan dependensi mereka secara lebih alami. Hal ini selanjutnya memungkinkan resume_foreground untuk mendukung tidak hanya melanjutkan eksekusi pada Windows::UI::Core::CoreDispatcher tertentu, tetapi kini juga mendukung melanjutkan eksekusi pada Windows::System::DispatcherQueue tertentu. Sebelumnya, hanya satu yang dapat didukung; tetapi tidak keduanya, karena definisi hanya dapat berada di satu namespace.
Berikut adalah contoh dukungan 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);
}
Pembantu koroutine sekarang juga dihiasi dengan [[nodiscard]], sehingga meningkatkan kegunaan mereka. Jika Anda lupa untuk co_await (atau tidak menyadari bahwa Anda harus melakukannya) agar semuanya berfungsi, maka karena [[nodiscard]], kesalahan seperti itu sekarang menghasilkan peringatan kompiler.
Bantuan dengan mendiagnosis alokasi langsung (tumpukan)
Karena nama kelas yang diproyeksikan dan nama kelas implementasi secara default sama, dan hanya berbeda pada namespace, keduanya mudah tertukar, sehingga implementasi dapat secara tidak sengaja dibuat di stack alih-alih menggunakan kelompok fungsi pembantu make. Ini mungkin sulit untuk didiagnosis dalam beberapa kasus, karena objek dapat dihancurkan saat referensi yang luar biasa masih dalam penerbangan. Asersi kini mendeteksi hal ini pada build debug. Meskipun pernyataan tidak mendeteksi alokasi tumpukan di dalam koroutin, namun sangat membantu dalam menangkap sebagian besar kesalahan tersebut.
Untuk informasi selengkapnya, lihat Mendiagnosis alokasi langsung.
Pembantu penangkapan yang ditingkatkan, dan delegasi variadik
Pembaruan ini memperbaiki batasan dengan pembantu penangkapan dengan mendukung jenis yang diproyeksikan juga. Hal ini kadang muncul pada API interop Windows Runtime saat API tersebut mengembalikan tipe proyeksi.
Pembaruan ini juga menambahkan dukungan untuk get_strong dan get_weak saat membuat delegasi variadik (non-Windows Runtime).
Dukungan untuk penghancuran yang ditangguhkan dan QI yang aman selama penghancuran
Bukan hal yang tidak lazim dalam destruktor objek kelas runtime untuk memanggil metode yang sementara menaikkan jumlah referensi. Saat jumlah referensi kembali ke nol, objek akan merusak untuk kedua kalinya. Dalam aplikasi XAML, Anda mungkin perlu melakukan QueryInterface (QI) di destruktor untuk memanggil implementasi pembersihan tertentu di atas atau di bawah hierarki. Tetapi jumlah referensi objek telah mencapai nol, sehingga QI juga merupakan pantulan jumlah referensi.
Pembaruan ini menambahkan dukungan untuk menstabilkan jumlah referensi, memastikan bahwa setelah jumlah referensi mencapai nol, nilainya tidak dapat aktif kembali; sambil tetap memungkinkan Anda melakukan QI untuk objek sementara apa pun yang diperlukan selama proses penghancuran. Prosedur ini tidak dapat dihindari pada aplikasi/kontrol XAML tertentu, dan C++/WinRT kini mampu menanganinya dengan baik.
Anda dapat menangguhkan penghancuran dengan menyediakan fungsi final_release statis pada jenis implementasi Anda. Pointer terakhir yang tersisa ke objek, dalam bentuk std::unique_ptr, diteruskan ke final_release Anda. Anda kemudian dapat memilih untuk memindahkan kepemilikan pointer tersebut ke beberapa konteks lain. Anda dapat dengan aman melakukan QI pada pointer tanpa menyebabkan penghancuran ganda. Namun, perubahan neto pada jumlah referensi harus bernilai nol saat objek dihancurkan.
Nilai pengembalian final_release dapat berupa void, objek operasi asinkron seperti IAsyncAction, atau 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.
}
};
Dalam contoh di bawah ini, setelah MainPage dirilis (untuk waktu terakhir), final_release dipanggil. Fungsi itu menunggu selama lima detik (di thread pool), lalu melanjutkan eksekusi dengan menggunakan Dispatcher milik halaman (yang memerlukan QI/AddRef/Release agar dapat berfungsi). Kemudian membersihkan sumber daya pada utas UI tersebut. Dan akhirnya membersihkan unique_ptr, yang menyebabkan destruktor MainPage benar-benar dipanggil. Bahkan dalam destruktor itu, DataContext dipanggil, yang memerlukan QI untuk IFrameworkElement.
Anda tidak harus menerapkan final_release sebagai coroutine. Namun, cara ini berhasil, dan sangat memudahkan untuk memindahkan proses penghancuran ke thread yang berbeda, dan itulah yang terjadi dalam contoh ini.
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;
}
};
Untuk informasi selengkapnya, lihat Penghancuran yang ditangguhkan.
Peningkatan dukungan untuk pewarisan antarmuka tunggal bergaya COM
Selain untuk pemrograman Windows Runtime, C++/WinRT juga digunakan untuk menulis dan menggunakan API khusus COM. Pembaruan ini memungkinkan untuk mengimplementasikan server COM di mana ada hierarki antarmuka. Ini tidak diperlukan untuk Windows Runtime; tetapi diperlukan untuk beberapa implementasi COM.
Penanganan parameter out yang benar
Bekerja dengan out parameter bisa jadi rumit; terutama array Windows Runtime. Dengan pembaruan ini, C++/WinRT jauh lebih andal dan tangguh terhadap kesalahan dalam menangani out parameter dan array; baik parameter tersebut berasal dari proyeksi bahasa maupun dari pengembang COM yang menggunakan ABI mentah dan keliru karena tidak menginisialisasi variabel secara konsisten. Dalam kedua kasus tersebut, C++/WinRT kini melakukan hal yang semestinya saat menyerahkan tipe proyeksi ke ABI (dengan memastikan bahwa setiap sumber daya yang terkait dilepaskan), serta saat menolkan atau membersihkan parameter yang diterima melalui ABI.
Event kini dapat menangani token yang tidak valid secara andal
Implementasi winrt::event sekarang dengan anggun menangani kasus di mana metode penghapusannya dipanggil dengan nilai token yang tidak valid (nilai yang tidak ada dalam array).
Variabel lokal coroutine sekarang dihancurkan sebelum coroutine kembali
Cara tradisional untuk menerapkan jenis koroutine dapat memungkinkan variabel lokal dalam koroutin dihancurkan setelah coroutine kembali/selesai (bukan sebelum suspensi akhir). Dimulainya kembali setiap pelayan sekarang ditangguhkan sampai penangguhan akhir, untuk menghindari masalah ini dan untuk mengumpulkan manfaat lain.
Berita, dan perubahan, dalam Windows SDK versi 10.0.17763.0 (Windows 10, versi 1809)
Tabel di bawah ini berisi berita dan perubahan untuk C++/WinRT di Windows SDK versi 10.0.17763.0 (Windows 10, versi 1809).
| Fitur baru atau yang diubah | Info lebih lanjut |
|---|---|
| Melanggar perubahan. Agar dapat dikompilasi, C++/WinRT tidak bergantung pada header dari SDK Windows. | Lihat Isolasi dari berkas header SDK Windows, di bawah ini. |
| Format sistem proyek Visual Studio telah berubah. | Lihat Cara menargetkan ulang proyek C++/WinRT Anda ke versi Windows SDK yang lebih baru, di bawah ini. |
| Ada fungsi dan kelas dasar baru untuk membantu Anda meneruskan objek koleksi ke fungsi Windows Runtime, atau untuk menerapkan properti koleksi dan jenis koleksi Anda sendiri. | Lihat Koleksi dengan C++/WinRT. |
| Anda dapat menggunakan ekstensi markup {Binding} dengan kelas runtime C++/WinRT Anda. | Untuk informasi selengkapnya, dan contoh kode, lihat Gambaran umum pengikatan data. |
| Dukungan untuk membatalkan coroutine memungkinkan Anda mendaftarkan panggilan balik pembatalan. | Untuk informasi selengkapnya, dan contoh kode, lihat Membatalkan operasi asinkron, dan panggilan balik pembatalan. |
| Saat membuat delegasi yang menunjuk ke fungsi anggota, Anda dapat membuat referensi yang kuat atau lemah ke objek saat ini (bukan mentah penunjuk ini ) pada titik di mana handler terdaftar. | Untuk informasi selengkapnya dan contoh kode, lihat subbagian Jika Anda menggunakan fungsi anggota sebagai delegasi di bagian Mengakses pointer this secara aman dengan delegasi penanganan peristiwa. |
| Bug yang terungkap akibat peningkatan kesesuaian Visual Studio terhadap standar C++ telah diperbaiki. Toolchain LLVM dan Clang juga lebih baik dimanfaatkan untuk memvalidasi kesamaan standar C++/WinRT. | Anda tidak akan lagi mengalami masalah yang dijelaskan dalam Mengapa proyek baru saya tidak akan dikompilasi? Saya menggunakan Visual Studio 2017 (versi 15.8.0 atau yang lebih baru), dan SDK versi 17134 |
Perubahan lainnya.
-
Melanggar perubahan.
winrt::get_abi(winrt::hstring const&) sekarang mengembalikan
void*alih-alihHSTRING. Anda dapat menggunakanstatic_cast<HSTRING>(get_abi(my_hstring));untuk mendapatkan HSTRING. Lihat Interoperabilitas dengan HSTRING milik ABI. -
Melanggar perubahan.
winrt::put_abi(winrt::hstring&) sekarang mengembalikan
void**alih-alihHSTRING*. Anda dapat menggunakanreinterpret_cast<HSTRING*>(put_abi(my_hstring));untuk mendapatkan HSTRING*. Lihat Interoperabilitas dengan HSTRING milik ABI. -
Melanggar perubahan. HRESULT sekarang diproyeksikan sebagai winrt::hresult. Jika Anda memerlukan HRESULT (untuk melakukan pemeriksaan tipe, atau untuk mendukung trait tipe), maka Anda dapat
static_castmembuat winrt::hresult. Jika tidak, winrt::hresult dikonversi ke HRESULT, selama Anda menyertakanunknwn.hsebelum Anda menyertakan header C++/WinRT apa pun. -
Melanggar perubahan. GUID sekarang diproyeksikan sebagai winrt::guid. Untuk API yang Anda terapkan, Anda harus menggunakan winrt::guid untuk parameter GUID. Jika tidak, winrt::guid dikonversi ke GUID, selama Anda menyertakan
unknwn.hsebelum Anda menyertakan header C++/WinRT apa pun. Lihat Mengoperasikan dengan struktur GUID ABI. - Melanggar perubahan. Konstruktor winrt::handle_type telah diperkuat dengan membuatnya eksplisit (sekarang lebih sulit untuk menulis kode yang salah dengannya). Jika Anda perlu menetapkan nilai handel mentah, panggil fungsi handle_type::attach sebagai gantinya.
-
Melanggar perubahan. Tanda tangan WINRT_CanUnloadNow dan WINRT_GetActivationFactory telah berubah. Anda tidak boleh mendeklarasikan fungsi-fungsi ini. Sebagai gantinya, sertakan
winrt/base.h(yang secara otomatis disertakan jika Anda menyertakan file header namespace Windows C++/WinRT) untuk menyertakan deklarasi fungsi ini. - Untuk struktur winrt::clock, from_FILETIME/to_FILETIME sudah tidak digunakan lagi dan digantikan oleh from_file_time/to_file_time.
- API yang disederhanakan yang mengharapkan parameter IBuffer . Sebagian besar API lebih suka koleksi, atau array. Tetapi kita merasa bahwa kita harus mempermudah untuk memanggil API yang mengandalkan IBuffer. Pembaruan ini menyediakan akses langsung ke data di balik implementasi IBuffer . Ini menggunakan konvensi penamaan data yang sama dengan yang digunakan oleh kontainer Pustaka Standar C++. Konvensi itu juga menghindari tabrakan dengan nama metadata yang secara konvensional dimulai dengan huruf besar.
- Peningkatan pembuatan kode: berbagai peningkatan untuk mengurangi ukuran kode, meningkatkan proses inlining, dan mengoptimalkan penyimpanan cache factory.
- Menghapus rekursi yang tidak perlu. Ketika baris perintah mengacu pada folder, alih-alih pada
.winmdtertentu, alatcppwinrt.exetidak lagi mencari file.winmdsecara rekursif. Alatcppwinrt.exeini kini juga menangani duplikat dengan lebih cerdas, sehingga lebih tahan terhadap kesalahan pengguna dan file.winmdyang tidak tersusun dengan baik. - Pointer pintar yang diperkeras. Sebelumnya, pencabut event gagal mencabut saat diberi nilai baru melalui move assignment. Ini membantu mengungkap masalah di mana kelas penunjuk pintar tidak menangani penugasan mandiri dengan andal; berakar dalam templat struct winrt::com_ptr. winrt::com_ptr telah diperbaiki, dan pembatal event juga telah diperbaiki agar dapat menangani semantik move dengan benar sehingga pembatalan dilakukan saat penetapan.
Important
Perubahan penting dilakukan pada C++/WinRT Visual Studio Extension (VSIX), keduanya dalam versi 1.0.181002.2, dan kemudian di versi 1.0.190128.4. Untuk detail perubahan ini, dan bagaimana perubahan tersebut memengaruhi proyek yang ada, Visual Studio dukungan untuk C++/WinRT dan Versi ekstensi VSIX sebelumnya.
Pemisahan dari file header Windows SDK
Ini berpotensi menjadi perubahan yang dapat menyebabkan kode Anda tidak lagi berfungsi.
Agar dapat dikompilasi, C++/WinRT tidak lagi bergantung pada file header dari SDK Windows. Berkas header di pustaka runtime C (CRT) dan Standard Template Library (STL) C++ juga tidak menyertakan header Windows SDK apa pun. Dan itu meningkatkan kepatuhan standar, menghindari dependensi yang tidak disengaja, dan sangat mengurangi jumlah makro yang harus Anda jaga.
Kemandirian ini berarti bahwa C++/WinRT sekarang lebih portabel dan sesuai standar, dan semakin memajukan kemungkinannya menjadi pustaka lintas kompilator dan lintas platform. Ini juga berarti bahwa header C++/WinRT tidak terpengaruh makro yang merugikan.
Jika sebelumnya Anda mengandalkan C++/WinRT untuk menyertakan header Windows apa pun dalam proyek Anda, kini Anda perlu menyertakannya sendiri. Apa pun itu, merupakan praktik terbaik untuk selalu secara eksplisit menyertakan header yang Anda perlukan, dan bukan membiarkan pustaka lain menyertakannya untuk Anda.
Saat ini, satu-satunya pengecualian terhadap isolasi file header Windows SDK adalah untuk intrinsik dan numerik. Tidak ada masalah yang diketahui dengan dependensi terakhir yang tersisa ini.
Dalam proyek Anda, Anda dapat mengaktifkan kembali interop dengan header SDK Windows jika Anda perlu melakukannya. Anda mungkin, misalnya, ingin mengimplementasikan antarmuka COM (berakar di IUnknown). Untuk contoh tersebut, sertakan unknwn.h sebelum Anda menyertakan header C++/WinRT apa pun. Melakukannya menyebabkan pustaka dasar C++/WinRT mengaktifkan berbagai kait untuk mendukung antarmuka COM klasik. Untuk contoh kode, lihat Menulis komponen COM dengan C++/WinRT. Demikian pula, secara eksplisit menyertakan header SDK Windows lainnya yang mendeklarasikan jenis dan/atau fungsi yang ingin Anda panggil.
Cara menargetkan ulang proyek C++/WinRT Anda ke versi SDK Windows yang lebih baru
Metode untuk mengalihkan target proyek Anda yang kemungkinan paling sedikit menimbulkan masalah pada compiler dan linker juga merupakan metode yang paling membutuhkan banyak tenaga. Metode tersebut melibatkan pembuatan proyek baru (menargetkan versi SDK Windows pilihan Anda), lalu menyalin file ke proyek baru Anda dari proyek lama Anda. Akan ada bagian dari file lama Anda .vcxproj dan .vcxproj.filters yang bisa langsung Anda salin agar Anda tidak perlu menambahkan file di Visual Studio.
Namun, ada dua cara lain untuk menargetkan ulang proyek Anda di Visual Studio.
- Buka properti proyek Versi Umum>Windows SDK, dan pilih Semua Konfigurasi dan Semua Platform. Atur versi SDK Windows ke versi yang ingin Anda targetkan.
- Di Penjelajah Solusi, klik kanan simpul proyek, klik Target ulang Proyek, pilih versi yang ingin Anda targetkan, lalu klik OK.
Jika Anda mengalami kesalahan pengkompilasi atau linker setelah menggunakan salah satu dari dua metode ini, maka Anda dapat mencoba membersihkan solusi (Build>Clean Solution dan/atau menghapus semua folder dan file sementara secara manual) sebelum mencoba membangun lagi.
Jika pengompilasi C++ menghasilkan "kesalahan C2039: 'IUnknown': bukan anggota ''namespace global''", tambahkan #include <unknwn.h> ke bagian atas file Anda pch.h (sebelum Anda menyertakan header C++/WinRT apa pun).
Anda mungkin juga perlu menambahkan #include <hstring.h> setelah itu.
Jika linker C++ menghasilkan "kesalahan LNK2019: simbol eksternal yang tidak terselesaikan _WINRT_CanUnloadNow@0 direferensikan dalam fungsi _VSDesignerCanUnloadNow@0", maka Anda dapat mengatasinya dengan menambahkan #define _VSDESIGNER_DONT_LOAD_AS_DLL ke file Anda pch.h .
Windows developer