Bagikan melalui


Pemecahan masalah C++/WinRT

Catatan

Untuk informasi tentang menginstal dan menggunakan C++/WinRT Visual Studio Extension (VSIX) (yang menyediakan dukungan templat proyek) lihat Dukungan Visual Studio untuk C++/WinRT.

Topik ini ada di depan sehingga Anda segera menyadarinya; bahkan jika Anda belum membutuhkannya. Tabel pemecahan masalah gejala dan solusi di bawah ini mungkin berguna bagi Anda apakah Anda memotong kode baru atau memindahkan aplikasi yang ada. Jika Anda melakukan porting, dan ingin menempa ke depan dan sampai ke tahap di mana proyek Anda dibangun dan dijalankan, maka Anda dapat membuat kemajuan sementara dengan mengomentari atau mengomentari kode yang tidak penting yang menyebabkan masalah, dan kemudian kembali untuk melunasi utang itu nanti.

Untuk daftar pertanyaan yang sering diajukan, lihat Tanya jawab umum.

Melacak masalah XAML

Pengecualian penguraian XAML mungkin sulit didiagnosis—terutama jika tidak ada pesan kesalahan yang bermakna dalam pengecualian. Pastikan debugger dikonfigurasi untuk menangkap pengecualian kesempatan pertama (untuk mencoba dan menangkap pengecualian penguraian sejak dini). Anda mungkin dapat memeriksa variabel pengecualian dalam debugger untuk menentukan apakah HRESULT atau pesan memiliki informasi yang berguna. Selain itu, periksa jendela output Visual Studio untuk output pesan kesalahan oleh pengurai XAML.

Jika aplikasi Anda berakhir dan yang Anda tahu adalah bahwa pengecualian yang tidak tertangani dilemparkan selama penguraian markup XAML, maka itu bisa menjadi hasil referensi (berdasarkan kunci) ke sumber daya yang hilang. Atau, itu bisa menjadi pengecualian yang dilemparkan di dalam UserControl, kontrol kustom, atau panel tata letak kustom. Upaya terakhir adalah pemisahan biner. Hapus sekitar setengah markup dari Halaman XAML dan jalankan kembali aplikasi. Anda kemudian akan tahu apakah kesalahan berada di suatu tempat di dalam setengah yang Anda hapus (yang sekarang harus Anda pulihkan dalam hal apa pun) atau setengahnya Anda tidak menghapus. Ulangi proses dengan memisahkan setengah yang berisi kesalahan, dan sebagainya, sampai Anda telah nol dalam masalah.

Gejala dan obat

Gejala Obat
Pengecualian dilemparkan pada runtime dengan nilai HRESULT REGDB_E_CLASSNOTREGISTERED. Lihat Mengapa saya mendapatkan pengecualian "kelas tidak terdaftar"?.
Pengkompilasi C++ menghasilkan kesalahan "'implements_type': bukan anggota kelas dasar langsung atau tidak langsung dari '<jenis> yang diproyeksikan'". Ini dapat terjadi ketika Anda memanggil make dengan nama yang tidak memenuhi syarat namespace dari jenis implementasi Anda (MyRuntimeClass, misalnya), dan Anda belum menyertakan header jenis tersebut. Pengkompilasi menafsirkan MyRuntimeClass sebagai jenis yang diproyeksikan. Solusinya adalah menyertakan header untuk jenis implementasi Anda (MyRuntimeClass.h, misalnya).
Pengkompilasi C++ menghasilkan kesalahan "mencoba mereferensikan fungsi yang dihapus". Ini dapat terjadi ketika Anda memanggil make dan jenis implementasi yang Anda lewati karena parameter templat memiliki = delete konstruktor default. Edit file header jenis implementasi dan ubah = delete ke = default. Anda juga dapat menambahkan konstruktor ke IDL untuk kelas runtime.
Anda telah menerapkan INotifyPropertyChanged, tetapi pengikatan XAML Anda tidak memperbarui (dan UI tidak berlangganan PropertyChanged). Ingatlah untuk mengatur Mode=OneWay (atau TwoWay) pada ekspresi pengikatan Anda di markup XAML. Lihat kontrol XAML; ikat ke properti C++/WinRT.
Anda mengikat kontrol item XAML ke koleksi yang dapat diamati, dan pengecualian dilemparkan pada runtime dengan pesan "Parameter salah". Dalam IDL dan implementasi Anda, deklarasikan koleksi yang dapat diamati sebagai jenis Windows.Foundation.Collections.IVector IInspectable>.< Tetapi kembalikan objek yang mengimplementasikan Windows.Foundation.Collections.IObservableVector<T>, di mana T adalah jenis elemen Anda. Lihat kontrol item XAML; ikat ke koleksi C++/WinRT.
Pengkompilasi C++ menghasilkan kesalahan formulir "'MyImplementationType_base<MyImplementationType>': tidak ada konstruktor default yang sesuai yang tersedia". Ini dapat terjadi ketika Anda berasal dari jenis yang memiliki konstruktor non-sepele. Konstruktor jenis turunan Anda perlu meneruskan parameter yang dibutuhkan konstruktor jenis dasar. Untuk contoh yang berfungsi, lihat Berasal dari jenis yang memiliki konstruktor non-sepele.
Pengkompilasi C++ menghasilkan kesalahan "tidak dapat mengonversi dari 'const std::vector<std::wstring,std::allocator<_Ty>>' menjadi 'const winrt::p aram::async_iterable<winrt::hstring> &'". Ini dapat terjadi ketika Anda meneruskan std::vector std::wstring ke Windows Runtime API yang mengharapkan koleksi. Untuk informasi selengkapnya, lihat Jenis data C++ Standar dan C++/WinRT.
Compiler C++ menghasilkan kesalahan "tidak dapat mengonversi dari 'const std::vector<winrt::hstring,std::allocator<_Ty>>' menjadi 'const winrt::p aram::async_iterable<winrt::hstring> &'". Ini dapat terjadi ketika Anda meneruskan std::vektor winrt::hstring ke API Windows Runtime asinkron yang mengharapkan koleksi, dan Anda belum menyalin atau memindahkan vektor ke callee asinkron. Untuk informasi selengkapnya, lihat Jenis data C++ Standar dan C++/WinRT.
Saat membuka proyek, Visual Studio menghasilkan kesalahan "Aplikasi untuk proyek tidak diinstal". Jika Anda belum melakukannya, Anda perlu menginstal alat Windows Universal untuk pengembangan C++ dari dalam dialog Proyek Baru Visual Studio. Jika itu tidak mengatasi masalah, proyek mungkin bergantung pada C++/WinRT Visual Studio Extension (VSIX) (lihat Dukungan Visual Studio untuk C++/WinRT.
Pengujian Windows App Certification Kit menghasilkan kesalahan bahwa salah satu kelas runtime Anda "tidak berasal dari kelas dasar Windows. Semua kelas yang dapat disusupi pada akhirnya harus berasal dari jenis di namespace Layanan Windows". Setiap kelas runtime (yang Anda deklarasikan dalam aplikasi Anda) yang berasal dari kelas dasar dikenal sebagai kelas yang dapat disusun. Kelas dasar utama dari kelas yang dapat disusupi harus merupakan jenis yang berasal dari namespace Windows.*; misalnya, Windows.UI.Xaml.DependencyObject. Lihat kontrol XAML; ikat ke properti C++/WinRT untuk detail selengkapnya.
Pengkompilasi C++ menghasilkan kesalahan "T harus jenis WinRT" untuk spesialisasi delegasi EventHandler atau TypedEventHandler. Pertimbangkan untuk menggunakan winrt::d elegate<... T> sebagai gantinya. Lihat Kejadian penulis di C++/WinRT.
Pengompilasi C++ menghasilkan kesalahan "T harus jenis WinRT" untuk spesialisasi operasi asinkron Windows Runtime. Pertimbangkan untuk mengembalikan tugas Pustaka Pola Paralel (PPL) sebagai gantinya. Lihat Operasi konkurensi dan asinkron.
Pengkompilasi C++ menghasilkan kesalahan "T harus jenis WinRT" ketika Anda memanggil winrt::xaml_typename. Gunakan jenis yang diproyeksikan dengan winrt::xaml_typename (misalnya, gunakan BgLabelControlApp::BgLabelControl), dan bukan jenis implementasi(misalnya, jangan gunakan BgLabelControlApp::implementation::BgLabelControl). Lihat kontrol kustom XAML (templat).
Pengkompilasi C++ menghasilkan "kesalahan C2220: peringatan diperlakukan sebagai kesalahan - tidak ada file 'objek' yang dihasilkan". Koreksi peringatan, atau atur C/C++>General>Treat Warnings Sebagai Kesalahan ke Tidak (/WX-).
Aplikasi Anda mengalami crash karena penanganan aktivitas di objek C++/WinRT Anda dipanggil setelah objek dihancurkan. Lihat Mengakses pointer ini dengan aman dengan delegasi penanganan peristiwa.
Pengkompilasi C++ menghasilkan "kesalahan C2338: Ini hanya untuk dukungan ref yang lemah". Anda meminta referensi lemah untuk jenis yang melewati struktur penanda winrt::no_weak_ref sebagai argumen templat ke kelas dasarnya. Lihat Menolak dukungan referensi yang lemah.
Pengompilasi C++ menghasilkan "consume_Something: fungsi yang mengembalikan 'otomatis' tidak dapat digunakan sebelum ditentukan" Lihat C3779: Mengapa pengompilasi memberi saya kesalahan "consume_Something:: fungsi yang mengembalikan 'otomatis' tidak dapat digunakan sebelum ditentukan"?.
Linker C++ menghasilkan "kesalahan LNK2019: Simbol eksternal yang tidak terselesaikan" Lihat Mengapa linker memberi saya kesalahan "LNK2019: Simbol eksternal yang tidak terselesaikan"?.
Toolchain LLVM dan Clang menghasilkan kesalahan saat digunakan dengan C++/WinRT. Kami tidak mendukung TOOLchain LLVM dan Clang untuk C++/WinRT, tetapi jika Anda ingin meniru cara kami menggunakannya secara internal, maka Anda dapat mencoba eksperimen seperti yang dijelaskan di Dapatkah saya menggunakan LLVM/Clang untuk mengkompilasi dengan C++/WinRT?.
Pengkompilasi C++ menghasilkan "tidak ada konstruktor default yang sesuai yang tersedia" untuk jenis yang diproyeksikan. Jika Anda mencoba menunda inisialisasi objek kelas runtime, atau untuk mengonsumsi dan mengimplementasikan kelas runtime dalam proyek yang sama, Maka Anda harus memanggil konstruktor std::nullptr_t . Untuk informasi selengkapnya, lihat Menggunakan API dengan C++/WinRT.
Pengkompilasi C++ menghasilkan "kesalahan C3861: 'from_abi': pengidentifikasi tidak ditemukan", dan kesalahan lain yang berasal dari base.h. Anda mungkin melihat kesalahan ini jika Anda menggunakan Visual Studio 2017 (versi 15.8.0 atau yang lebih baru), dan menargetkan Windows SDK versi 10.0.17134.0 (Windows 10, versi 1803). Targetkan versi Windows SDK yang lebih baru (lebih sesuai), atau atur properti proyek C/C++>Mode Kesuaian Bahasa>: Tidak (juga, jika /permisif- muncul di properti proyek C/C++>Language>Command Line di bawah Opsi Tambahan, lalu hapus).
Pengompilasi C++ menghasilkan "kesalahan C2039: 'IUnknown': bukan anggota ''namespace global''". Lihat Cara menargetkan ulang proyek C++/WinRT Anda ke versi Windows SDK yang lebih baru.
Linker C++ menghasilkan "kesalahan LNK2019: simbol eksternal yang tidak terselesaikan _WINRT_CanUnloadNow@0 direferensikan dalam _VSDesignerCanUnloadNow@0 fungsi" Lihat Cara menargetkan ulang proyek C++/WinRT Anda ke versi Windows SDK yang lebih baru.
Proses build menghasilkan pesan kesalahan C++/WinRT VSIX tidak lagi menyediakan dukungan build proyek. Tambahkan referensi proyek ke paket Nuget Microsoft.Windows.CppWinRT. Instal paket NuGet Microsoft.Windows.CppWinRT ke dalam proyek Anda. Untuk detailnya, lihat Versi ekstensi VSIX yang lebih lama.
Linker C++ menghasilkan kesalahan LNK2019: simbol eksternal yang tidak terselesaikan, dengan penyebutan winrt::impl::consume_Windows_Foundation_Collections_IVector. Pada C++/WinRT 2.0, Jika Anda menggunakan rentang berdasarkan for koleksi Windows Runtime, maka Anda sekarang perlu #include <winrt/Windows.Foundation.Collections.h>.
Pengkompilasi C++ menghasilkan "kesalahan C4002: Terlalu banyak argumen untuk pemanggilan makro seperti fungsi GetCurrentTime". Lihat Bagaimana cara mengatasi ambiguitas dengan GetCurrentTime dan/atau TRY?.
Pengkompilasi C++ menghasilkan "kesalahan C2334: token tak terduga sebelumnya '{'; melompati isi fungsi yang jelas". Lihat Bagaimana cara mengatasi ambiguitas dengan GetCurrentTime dan/atau TRY?.
Pengkompilasi C++ menghasilkan "winrt::impl::p roduce<D,saya> tidak dapat membuat instans kelas abstrak, karena GetBindingConnector hilang". Anda perlu #include <winrt/Windows.UI.Xaml.Markup.h>.
Pengkompilasi C++ menghasilkan "kesalahan C2039: 'promise_type': bukan anggota 'std::experimental::coroutine_traits<void>'". Koroutin Anda perlu mengembalikan objek operasi asinkron, atau winrt::fire_and_forget. Lihat Operasi konkurensi dan asinkron.
Proyek Anda menghasilkan "akses ambigu 'PopulatePropertyInfoOverride'". Kesalahan ini dapat terjadi ketika Anda mendeklarasikan satu kelas dasar di IDL Anda dan kelas dasar yang berbeda di markup XAML Anda.
Memuat solusi C++/WinRT untuk pertama kalinya menghasilkan "Build designtime gagal untuk konfigurasi proyek 'MyProject.vcxproj' 'Debug|x86'. IntelliSense mungkin tidak tersedia.". Masalah IntelliSense ini akan diselesaikan setelah Anda membangun untuk pertama kalinya.
Mencoba menentukan winrt::auto_revoke saat mendaftarkan delegasi menghasilkan pengecualian winrt::hresult_no_interface. Lihat Apakah delegasi pencabutan otomatis Anda gagal mendaftar.
Dalam aplikasi C++/WinRT, saat menggunakan komponen C# Windows Runtime yang menggunakan XAML, kompilator menghasilkan kesalahan formulir "'MyNamespace_XamlTypeInfo': bukan anggota 'winrt::MyNamespace'"—di mana MyNamespace adalah nama namespace komponen Windows Runtime. Di pch.h aplikasi C++/WinRT yang mengkonsumsi, tambahkan #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>—mengganti MyNamespace sebagaimana mestinya.
Dalam proyek C++/WinRT di Visual Studio, IntelliSense menghasilkan kesalahan formulir "kesalahan E1696: tidak dapat sumber terbuka file". Kompilasi proyek yang baru Anda buat setidaknya sekali. Kemudian klik kanan di editor >kode sumber Rescan Rescan>File. Itu akan mengatasi semua kesalahan IntelliSense, termasuk E1696.

Catatan

Jika topik ini tidak menjawab pertanyaan Anda, maka Anda mungkin menemukan bantuan dengan mengunjungi komunitas pengembang Visual Studio C++, atau dengan menggunakan c++-winrt tag di Stack Overflow.