Partager via


Résolution des problèmes liés à C++/WinRT

Notes

Pour plus d’informations sur l’installation et l’utilisation de l’extension VSIX (Visual Studio Extension) C++/WinRT (qui prend en charge les modèles de projet), consultez Prise en charge de Visual Studio pour C++/WinRT.

Cette rubrique est fournie en amont pour que vous en ayez connaissance immédiatement, même si vous n’en avez pas encore l’utilité. Le tableau des symptômes et solutions de problèmes ci-après peut vous être utile, que vous coupiez un nouveau code ou portiez une application existante. Si vous effectuez un portage et que vous êtes impatient d’avancer et de passer à la phase de génération et d’exécution de votre projet, progressez provisoirement en commentant ou en remplaçant le code non essentiel problématique, puis revenez plus tard combler ce qui manque.

Pour obtenir la liste des questions fréquentes, consultez Questions fréquentes (FAQ).

Suivi des problèmes XAML

Les exceptions d’analyse XAML peuvent être difficiles à diagnostiquer, en particulier si l’exception ne présente aucun message d’erreur explicite. Assurez-vous que le débogueur est configuré pour intercepter les exceptions de première chance (pour essayer d’intercepter l’exception d’analyse le plus tôt possible). Vous pourrez peut-être inspecter la variable d’exception dans le débogueur pour déterminer si la valeur HRESULT ou le message comportent des informations utiles. Vérifiez également la fenêtre de sortie de Visual Studio pour voir si elle contient des messages d’erreur de l’analyseur XAML.

Si votre application s’arrête et que vous savez simplement qu’une exception non prise en charge a été levée pendant l’analyse des balises XAML, cela peut être le résultat d’une référence (par clé) à une ressource manquante. Il peut également s’agir d’une exception levée dans un UserControl, un contrôle personnalisé ou un panneau de disposition personnalisé. En dernier recours, vous pouvez effectuer un fractionnement binaire. Supprimez environ la moitié des balises d’une page XAML et réexécutez l’application. Vous saurez alors si l’erreur se situe quelque part dans la partie que vous avez supprimée (que vous devez maintenant restaurer dans tous les cas), ou dans la partie que vous n’avez pas supprimée. Répétez ce processus en fractionnant la moitié qui contient l’erreur et ainsi de suite jusqu’à ce que vous ayez ciblé le problème.

Symptômes et solutions

Symptôme Solution
Une exception est levée au moment de l’exécution avec une valeur HRESULT égale à REGDB_E_CLASSNOTREGISTERED. Consultez Pourquoi suis-je confronté à l’exception « classe non enregistrée » ?.
Le compilateur C++ génère l’erreur « 'implements_type' : n’est membre d’aucune classe de base directe ou indirecte de '<type projeté>' ». Cela peut se produire quand vous appelez make avec le nom complet de l’espace de noms de votre type d’implémentation (MyRuntimeClass, par exemple), et que vous n’avez pas encore inclus l’en-tête de ce type. Le compilateur interprète MyRuntimeClass en tant que type projeté. La solution consiste à inclure l’en-tête de votre type d’implémentation (MyRuntimeClass.h, par exemple).
Le compilateur C++ génère l’erreur « tentative de référencement d’une fonction supprimée ». Cela peut arriver quand vous appelez make et que le type d’implémentation que vous passez en tant que paramètre de modèle a un constructeur par défaut = delete. Modifiez le fichier d’en-tête du type d’implémentation et remplacez = delete par = default. Vous pouvez également ajouter un constructeur dans le fichier IDL pour la classe runtime.
Vous avez implémenté INotifyPropertyChanged, mais vos liaisons XAML ne sont pas mises à jour (et l’IU ne s’abonne pas à PropertyChanged). Veillez à définir Mode=OneWay (ou TwoWay) pour votre expression de liaison dans les balises XAML. Consultez Contrôles XAML ; liaison à une propriété C++/WinRT.
Vous liez un contrôle d’éléments XAML à une collection observable, et une exception est levée au moment de l’exécution avec le message « Le paramètre n’est pas correct ». Dans votre fichier IDL et votre implémentation, déclarez toute collection observable en tant que type Windows.Foundation.Collections.IVector<IInspectable>. Toutefois, retournez un objet qui implémente Windows.Foundation.Collections.IObservableVector<T>, où T est votre type d’élément. Consultez Contrôles d’éléments XAML ; liaison à une collection C++/WinRT.
Le compilateur C++ génère l’erreur suivante : « 'MyImplementationType_base<MyImplementationType>' : aucun constructeur par défaut approprié disponible ». Cela peut se produire en cas de dérivation à partir d’un type ayant un constructeur non trivial. Le constructeur de votre type dérivé doit passer les paramètres nécessaires au constructeur du type de base. Pour un exemple pratique, consultez Dérivation à partir d’un type qui possède un constructeur non trivial.
Le compilateur C++ génère l’erreur suivante : « Impossible de convertir 'const std::vector<std::wstring,std::allocator<_Ty>>' en 'const winrt::param::async_iterable<winrt::hstring> &' ». Cela peut se produire quand vous passez un std::vector de std::wstring à une API Windows Runtime qui attend une collection. Pour plus d’informations, consultez Types de données C++ standard et C++/WinRT.
Le compilateur C++ génère l’erreur suivante : « Impossible de convertir 'const std::vector<winrt::hstring,std::allocator<_Ty>>' en 'const winrt::param::async_iterable<winrt::hstring> &' ». Cela peut se produire quand vous passez un std::vector de winrt::hstring à une API Windows Runtime asynchrone qui attend une collection, et que vous n’avez ni copié, ni déplacé le vecteur vers l’appelé asynchrone. Pour plus d’informations, consultez Types de données C++ standard et C++/WinRT.
Quand vous ouvrez un projet, Visual Studio génère l’erreur suivante : « L’application du projet n’est pas installée ». Si vous ne l’avez pas déjà fait, installez les outils Windows universels pour développer en C++ à partir de la boîte de dialogue Nouveau projet de Visual Studio. Si cela ne résout pas le problème, le projet peut dépendre de l’extension Visual Studio (VSIX) C++/WinRT (consultez Prise en charge de Visual Studio pour C++/WinRT.
Les tests du Kit de certification des applications Windows génèrent une erreur indiquant que l’une de vos classes runtime « ne dérive pas d’une classe de base Windows. Toutes les classes composables doivent en définitive dériver d’un type de l’espace de noms Windows ». Toute classe runtime (que vous déclarez dans votre application) qui dérive d’une classe de base est appelée classe composable. La classe de base ultime d’une classe composable doit être un type provenant d’un espace de noms Windows.*, par exemple Windows.UI.Xaml.DependencyObject. Pour plus d’informations, consultez Contrôles XAML ; liaison à une propriété C++/WinRT.
Le compilateur C++ génère une erreur « T must be WinRT type » (T doit être de type WinRT) pour une spécialisation de délégué EventHandler ou TypedEventHandler. Utilisez winrt::delegate<...T> à la place. Consultez Créer des événements en C++/WinRT.
Le compilateur C++ génère une erreur « T must be WinRT type » (T doit être de type WinRT) pour une spécialisation d’opération asynchrone Windows Runtime. Retournez une tâche PPL (Parallel Patterns Library) à la place. Consultez Opérations concurrentes et asynchrones.
Le compilateur C++ génère une erreur « T must be WinRT type » (T doit être de type WinRT) quand vous appelez winrt::xaml_typename. Utilisez le type projeté avec winrt::xaml_typename (par exemple, utilisez BgLabelControlApp::BgLabelControl), et non le type d’implémentation (par exemple, n’utilisez pas BgLabelControlApp::implementation::BgLabelControl). Consultez Contrôles XAML personnalisés (basés sur un modèle).
Le compilateur C++ génère l’« erreur C2220 : avertissement traité en tant qu’erreur - aucun fichier 'object' généré ». Corrigez l’avertissement ou affectez à C/C++>Général>Considérer les avertissements comme des erreurs la valeur Non (/WX-) .
Votre application plante, car un gestionnaire d’événements dans votre objet C++/WinRT est appelé après la destruction de l’objet. Consultez accès sécurisé au pointeur this avec un délégué de gestion des événements.
Le compilateur C++ génère l’« erreur C2338 : ceci est réservé à la prise en charge des références faibles ». Vous demandez une référence faible pour un type qui a passé le struct de marqueur winrt::no_weak_ref en tant qu’argument de modèle à sa classe de base. Consultez Refus de la prise en charge des références faibles.
Le compilateur C++ produit « consume_Something : une fonction qui renvoie 'auto' ne peut pas être utilisée avant d’être définie » Consultez C3779 : Pourquoi le compilateur affiche-t-il l’erreur « consume_Something : une fonction qui renvoie 'auto' ne peut pas être utilisée avant d’être définie » ?.
L’éditeur de liens C++ génère l’« erreur LNK2019 : symbole externe non résolu » Consultez Pourquoi l’éditeur de liens retourne-t-il une erreur « LNK2019 : symbole externe non résolu » ?.
La chaîne d’outils LLVM et Clang génère des erreurs quand elle est utilisée avec C++/WinRT. Nous ne prenons pas en charge la chaîne d’outils LLVM et Clang pour C++/WinRT, mais si vous souhaitez émuler notre mode d’utilisation interne, vous pouvez essayer la méthode décrite dans Puis-je utiliser LLVM/Clang pour compiler avec C++/WinRT ?.
Le compilateur C++ génère l’erreur « aucun constructeur par défaut approprié disponible » pour un type projeté. Si vous essayez de retarder l’initialisation d’un objet de classe runtime, ou de consommer et d’implémenter une classe runtime dans le même projet, vous devez appeler le constructeur std::nullptr_t. Pour plus d’informations, consultez Utiliser des API avec C++/WinRT.
Le compilateur C++ génère l’« erreur C3861 : 'from_abi' : identificateur introuvable » et d’autres erreurs provenant de base.h. Vous pouvez voir cette erreur si vous utilisez Visual Studio 2017 (version 15.8.0 ou ultérieure) et si vous ciblez le kit SDK Windows version 10.0.17134.0 (Windows 10, version 1803). Ciblez une version ultérieure (plus conforme) du kit SDK Windows, ou définissez la propriété de projet C/C++>Langage>Mode de conformité : Non (de plus, si /permissive- apparaît dans la propriété de projet C/C++>Langage>Ligne de commande sous Options supplémentaires, supprimez-la).
Le compilateur C++ génère « Erreur C2039 : 'IUnknown' : n’est pas membre de ''l’espace de noms global'' ». Consultez Guide pratique pour recibler votre projet C++/WinRT vers une version ultérieure du SDK Windows.
Si l’éditeur de liens C++ génère l’« erreur LNK2019 : symbole externe non résolu _WINRT_CanUnloadNow@0 référencé dans la fonction _VSDesignerCanUnloadNow@0 » Consultez Guide pratique pour recibler votre projet C++/WinRT vers une version ultérieure du SDK Windows.
Le processus de build génère le message d’erreur suivant : Le VSIX C++/WinRT ne fournit plus la prise en charge de la génération de projet. Ajoutez une référence de projet au package NuGet Microsoft.Windows.CppWinRT. Installez le package NuGet Microsoft.Windows.CppWinRT dans votre projet. Pour plus d’informations, consultez Versions antérieures de l’extension VSIX.
L’éditeur de liens C++ génère l’« erreur LNK2019 : symbole externe non résolu en faisant mention à winrt::impl::consume_Windows_Foundation_Collections_IVector. Depuis C++/WinRT 2.0, si vous utilisez un for basé sur une plage dans une collection Windows Runtime, vous devez désormais #include <winrt/Windows.Foundation.Collections.h>.
Le compilateur C++ génère « Erreur C4002 : trop d’arguments pour l’appel de macro de type fonction GetCurrentTime ». Consultez Comment faire pour résoudre les ambiguïtés avec GetCurrentTime et/ou TRY ?.
Le compilateur C++ génère « Erreur C2334 : jetons inattendus avant '{' ; corps apparent de la fonction ignoré ». Consultez Comment faire pour résoudre les ambiguïtés avec GetCurrentTime et/ou TRY ?.
Le compilateur C++ génère « winrt::impl::produce<D,I> ne peut pas instancier une classe abstraite en raison d’un GetBindingConnector manquant ». Vous devez utiliser #include <winrt/Windows.UI.Xaml.Markup.h>.
Le compilateur C++ génère « Erreur C2039 : 'promise_type': n’est pas membre de 'std::experimental::coroutine_traits<void>' ». Votre coroutine doit retourner un objet d’opération asynchrone ou winrt::fire_and_forget. Consultez Opérations concurrentes et asynchrones.
Votre projet génère « accès ambigu de 'PopulatePropertyInfoOverride' ». Cette erreur peut se produire quand vous déclarez une classe de base dans votre IDL et une autre classe de base dans votre balisage XAML.
La première fois que vous chargez une solution C++/WinRT, vous obtenez : « Échec de la build au moment du design pour le projet 'MyProject.vcxproj' et la configuration 'Debug|x86'. IntelliSense est peut-être indisponible. ». Ce problème lié à IntelliSense est résolu après la première génération.
Toute tentative de spécification de winrt::auto_revoke au moment de l’inscription d’un délégué produit une exception winrt::hresult_no_interface. Consultez Si votre délégué à révocation automatique ne parvient pas à s’inscrire.
Dans une application C++/WinRT, lors de l’utilisation d’un composant Windows Runtime C# qui utilise XAML, le compilateur génère une erreur au format « 'MyNamespace_XamlTypeInfo' : n’est pas un membre de 'winrt::MyNamespace' », où MyNamespace est le nom de l’espace de noms du composant Windows Runtime. Dans pch.h, dans l’application qui utilise C++/WinRT, ajoutez #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h> pour remplacer MyNamespace de manière appropriée.
Dans un projet C++/WinRT dans Visual Studio, IntelliSense génère une erreur au format « Erreur E1696 : impossible d’ouvrir le fichier source ». Compilez au moins une fois votre projet nouvellement créé. Cliquez ensuite avec le bouton droit dans l’éditeur de code source >Réanalyser>Réanalyser le fichier. Cela résout toutes les erreurs IntelliSense, y compris l’erreur E1696.

Notes

Si cette rubrique n’a pas répondu à votre question, vous pouvez rechercher de l’aide en accédant à la page de la Communauté de développeurs Visual Studio C++ ou en utilisant la balise c++-winrt sur Stack Overflow.