Freigeben über


Fehlerbehebung bei C++/WinRT-Problemen

Hinweis

Informationen zum Installieren und Verwenden der C++/WinRT Visual Studio Extension (VSIX) (die Projektvorlagenunterstützung bereitstellt) finden Sie unter Visual Studio-Unterstützung für C++/WinRT.

Dieses Thema steht an erster Stelle, damit Sie sofort davon Kenntnis nehmen, auch wenn Sie es noch nicht benötigen. Die nachstehende Tabelle mit Problembehandlungssymptomen und Abhilfemaßnahmen kann hilfreich für Sie sein, unabhängig davon, ob Sie neuen Code ausschneiden oder eine vorhandene App portieren. Wenn Sie portieren und bereit sind, voranzukommen und die Phase zu erreichen, in der Ihr Projekt erstellt und ausgeführt wird, können Sie vorübergehende Fortschritte erzielen, indem Sie den nicht wesentlichen Code, der Probleme verursacht, auskommentieren oder vorübergehend entfernen und später darauf zurückkommen, um die Schulden zu begleichen.

Eine Liste der häufig gestellten Fragen finden Sie unter Häufig gestellte Fragen.

Nachverfolgen von XAML-Problemen

XAML-Analyseausnahmen können schwierig zu diagnostizieren sein – insbesondere, wenn in der Ausnahme keine aussagekräftigen Fehlermeldungen vorhanden sind. Stellen Sie sicher, dass der Debugger so konfiguriert ist, dass 'First-Chance-Ausnahmen' erfasst werden (um die Parsing-Ausnahme frühzeitig abzufangen). Möglicherweise können Sie die Ausnahmevariable im Debugger überprüfen, um festzustellen, ob das HRESULT oder die Nachricht nützliche Informationen enthält. Überprüfen Sie außerdem das Ausgabefenster von Visual Studio auf Fehlermeldungen, die vom XAML-Parser ausgegeben werden.

Wenn Ihre App beendet wird und Sie nur wissen, dass während der XAML-Markupanalyse eine unbehandelte Ausnahme ausgelöst wurde, kann dies das Ergebnis eines Verweises (nach Schlüssel) auf eine fehlende Ressource sein. Es könnte sich auch um eine Ausnahme innerhalb eines UserControl-Steuerelements, eines benutzerdefinierten Steuerelements oder eines benutzerdefinierten Layoutpanels handeln. Eine letzte Möglichkeit ist eine binäre Aufteilung. Entfernen Sie etwa die Hälfte des Markups von einer XAML-Seite, und führen Sie die App erneut aus. Sie werden dann wissen, ob sich der Fehler in der Hälfte befindet, die Sie entfernt haben (die Sie jetzt in jedem Fall wiederherstellen sollten) oder in der Hälfte, die Sie nicht entfernt haben. Wiederholen Sie den Vorgang, indem Sie die Hälfte, die den Fehler enthält, teilen und so weiter, bis Sie sich auf das Problem fokussiert haben.

Symptome und Heilmittel

Symptom Heilmittel
Zur Laufzeit wird eine Ausnahme mit einem HRESULT-Wert von REGDB_E_CLASSNOTREGISTERED ausgelöst. Lesen Sie Warum erhalte ich eine Ausnahme "Klasse nicht registriert"?.
Der C++-Compiler erzeugt den Fehler "'implements_type': ist kein Mitglied einer direkten oder indirekten Basisklasse des '<projizierten Typs>'". Dies kann passieren, wenn Sie mit dem namespace-unqualifizierten Namen Ihres Implementierungstyps (z. B.MyRuntimeClass) aufrufen, und Sie haben den Header dieses Typs nicht eingeschlossen. Der Compiler interpretiert MyRuntimeClass als projizierten Typ. Die Lösung besteht darin, den Header für Ihren Implementierungstyp (z. B.MyRuntimeClass.h) einzuschließen.
Der C++-Compiler erzeugt den Fehler "versucht, auf eine gelöschte Funktion zu verweisen". Dies kann passieren, wenn Sie aufrufen und der Implementierungstyp, den Sie als Vorlagenparameter übergeben, einen = delete-Standardkonstruktor hat. Bearbeiten Sie die Headerdatei des Implementierungstyps, und ändern Sie = delete in = default. Sie können auch einen Konstruktor zur IDL für die Laufzeitklasse hinzufügen.
Sie haben INotifyPropertyChangedimplementiert, Ihre XAML-Bindungen werden jedoch nicht aktualisiert (und die Benutzeroberfläche registriert sich nicht für PropertyChanged). Denken Sie daran, Mode=OneWay (oder TwoWay) für den Bindungsausdruck im XAML-Markup festzulegen. Siehe XAML-Steuerelemente; an eine C++/WinRT-Eigenschaftbinden.
Sie binden ein XAML-Elementsteuerelement an eine feststellbare Auflistung, und eine Ausnahme wird zur Laufzeit mit der Meldung "Der Parameter ist falsch" ausgelöst. Deklarieren Sie in Ihrer IDL und Ihrer Implementierung jede beobachtbare Auflistung als Typ Windows.Foundation.Collections.IVector<IInspectable>. Geben Sie jedoch ein Objekt zurück, das Windows.Foundation.Collections.IObservableVector<T>implementiert, wobei T der Elementtyp ist. Siehe XAML-Elementsteuerelemente; binden an eine C++/WinRT-Auflistung.
Der C++-Compiler erzeugt einen Fehler des Formulars "'MyImplementationType_base<MyImplementationType>': kein geeigneter Standardkonstruktor verfügbar". Dies kann passieren, wenn Sie von einem Typ abgeleitet haben, der über einen nicht trivialen Konstruktor verfügt. Der Konstruktor des abgeleiteten Typs muss die Parameter übergeben, die der Konstruktor des Basistyps benötigt. Ein ausgearbeitetes Beispiel finden Sie unter Ableiten eines Typs mit einem nicht trivialen Konstruktor.
Der C++-Compiler erzeugt den Fehler "kann nicht von 'const std::vector<std::wstring,std::allocator<_Ty>>' in 'const winrt::param::async_iterable<winrt::hstring> &'" konvertieren. Dies kann passieren, wenn Sie einen std::vector von std::wstring an eine Windows Runtime API übergeben, die eine Sammlung erwartet. Weitere Informationen finden Sie unter Standard-C++-Datentypen und C++/WinRT.
Der C++-Compiler erzeugt den Fehler "kann nicht aus 'const std::vector<winrt::hstring,std::allocator<_Ty>>' in 'const winrt::param::async_iterable<winrt::hstring> &' konvertieren". Dies kann passieren, wenn Sie einen std::vector von winrt::hstring an eine asynchrone Windows-Runtime-API übergeben, die eine Auflistung erwartet, und weder den Vektor kopiert noch an den asynchronen Aufrufer übergeben haben. Weitere Informationen finden Sie unter Standard-C++-Datentypen und C++/WinRT.
Beim Öffnen eines Projekts erzeugt Visual Studio den Fehler "Die Anwendung für das Projekt wird nicht installiert". Falls noch nicht geschehen, müssen Sie Universelle Windows-Tools für die C++-Entwicklung aus dem Dialogfeld Neues Projekt von Visual Studio installieren. Wenn das Problem dadurch nicht behoben wird, hängt das Projekt möglicherweise von der C++/WinRT Visual Studio-Erweiterung (VSIX) ab (siehe Visual Studio-Unterstützung für C++/WinRT.
Das Windows-App-Zertifizierungskit meldet einen Fehler: Eine Ihrer Laufzeitklassen „“ ist nicht von einer Windows-Basisklasse abgeleitet. Alle komponierbaren Klassen müssen letztendlich von einem Typ im Windows-Namespace „“ abgeleitet sein. Jede Laufzeitklasse (die Sie in Ihrer Anwendung deklarieren), die von einer Basisklasse abgeleitet wird, wird als komponierbare-Klasse bezeichnet. Die ultimative Basisklasse einer komponierbaren Klasse muss ein Typ sein, der aus einem Windows.* -Namespace stammt; beispiel: Windows.UI.Xaml.DependencyObject. Weitere Informationen finden Sie unter XAML-Steuerelemente und binden Sie an eine C++/WinRT-Eigenschaft.
Der C++-Compiler erzeugt einen "T muss WinRT-Typ" Fehler für eine EventHandler- oder TypedEventHandler-Stellvertretungsspezialisierung sein. Erwägen Sie die Verwendung winrt::delegate<...T> statt. Siehe Autor-Ereignisse in C++/WinRT.
Der C++-Compiler meldet einen Fehler mit der Nachricht 'T muss WinRT-Typsein' für eine Spezialisierung einer asynchronen Windows-Runtime-Operation. Erwägen Sie stattdessen, eine Aufgabe der Parallel Patterns Library (PPL) zurückzugeben. Siehe Parallelität und asynchrone Vorgänge.
Der C++-Compiler erzeugt einen Fehler „T muss WinRT-Typsein“, wenn Sie winrt::xaml_typenameaufrufen. Verwenden Sie den projizierten Typ mit winrt::xaml_typename (verwenden Sie z. B. BgLabelControlApp::BgLabelControl), und nicht den Implementierungstyp(z. B. nicht BgLabelControlApp::implementation::BgLabelControl). Siehe vorlagenbasierte, benutzerdefinierte XAML-Steuerelemente.
Der C++-Compiler erzeugt "Fehler C2220: Warnung als Fehler behandelt - keine 'Objekt'-Datei generiert". Korrigieren Sie die Warnung, oder setzen Sie C/C++>Allgemein>Warnungen als Fehler behandeln auf Nein (/WX-).
Ihre App stürzt ab, da ein Ereignishandler in Ihrem C++/WinRT-Objekt aufgerufen wird, nachdem das Objekt zerstört wurde. Weitere Informationen finden Sie unter Sicheren Zugriff auf die diesem Zeiger mit einem Ereignisbehandlungsdelegat.
Der C++-Compiler erzeugt "Fehler C2338: Dies gilt nur für schwache Ref-Unterstützung". Sie fordern einen schwachen Verweis für einen Typ an, der die winrt::no_weak_ref Markerstruktur als Vorlagenargument an die Basisklasse übergeben hat. Siehe Abmelden von schwacher Referenzunterstützung.
Der C++-Compiler erzeugt "consume_Something: Funktion, die 'auto' zurückgibt, kann nicht genutzt werden, bevor sie definiert ist". Siehe C3779: Warum gibt der Compiler mir den Fehler "consume_Something: Eine Funktion, die 'auto' zurückgibt, kann nicht verwendet werden, bevor sie definiert wird"?.
Der C++-Linker erzeugt "Fehler LNK2019: Nicht aufgelöstes externes Symbol" Lesen Sie Warum zeigt der Linker mir einen Fehler „LNK2019: Nicht aufgelöstes externes Symbol“?.
Die LLVM- und Clang-Toolkette erzeugt Fehler, wenn sie mit C++/WinRT verwendet werden. Wir unterstützen die LLVM- und Clang-Toolkette für C++/WinRT nicht, aber wenn Sie emulieren möchten, wie wir sie intern verwenden, können Sie ein Experiment wie das im Abschnitt beschriebenen „Kann ich LLVM/Clang zum Kompilieren mit C++/WinRT verwenden?“ausprobieren.
Der C++-Compiler erzeugt die Fehlermeldung "kein geeigneter Standardkonstruktor verfügbar" für einen projizierten Typ. Wenn Sie versuchen, die Initialisierung eines Laufzeitklassenobjekts zu verzögern oder eine Laufzeitklasse im selben Projekt zu nutzen und zu implementieren, müssen Sie den std::nullptr_t-Konstruktor aufrufen. Weitere Informationen finden Sie unter Nutzen von APIs mit C++/WinRT.
Der C++-Compiler erzeugt "Fehler C3861: 'from_abi': Bezeichner nicht gefunden", und andere Fehler, die in base.hihren Ursprung haben. Dieser Fehler wird möglicherweise angezeigt, wenn Sie Visual Studio 2017 (Version 15.8.0 oder höher) verwenden und auf die Windows SDK-Version 10.0.17134.0 (Windows 10, Version 1803) abzielen. Wählen Sie entweder eine spätere (konformere) Version des Windows SDK aus, oder legen Sie die Projekteigenschaft C/C++>Sprache>Konformitätsmodus fest: Keine (auch, wenn /permissive- in der Projekteigenschaft C/C++>Sprache>Befehlszeile unter Zusätzliche Optionenangezeigt wird, löschen Sie es).
Der C++-Compiler erzeugt "Fehler C2039: 'IUnknown': ist kein Mitglied des 'global namespace'". Weitere Informationen finden Sie unter , wie Sie Ihr C++/WinRT-Projekt auf eine neuere Version des Windows SDK umstellen.
Der C++-Linker erzeugt "Fehler LNK2019: nicht aufgelöstes externes Symbol _WINRT_CanUnloadNow@0 verwendet in der Funktion _VSDesignerCanUnloadNow@0" Weitere Informationen finden Sie unter , wie Sie Ihr C++/WinRT-Projekt auf eine neuere Version des Windows SDK umstellen.
Der Buildprozess erzeugt die Fehlermeldung Der C++/WinRT VSIX bietet keine Projektbuildunterstützung mehr. Fügen Sie einen Projektverweis zum Microsoft.Windows.CppWinRT Nuget-Pakethinzu. Installieren Sie das Microsoft.Windows.CppWinRT NuGet-Paket in Ihrem Projekt. Ausführliche Informationen finden Sie unter Früheren Versionen der VSIX-Erweiterung.
Der C++-Linker erzeugt den Fehler LNK2019: nicht aufgelöstes externes Symbol, mit einer Erwähnung von winrt::impl::consume_Windows_Foundation_Collections_IVector. Ab C++/WinRT 2.0, wenn Sie eine bereichsbasierte for für eine Windows-Runtime-Auflistung verwenden, müssen Sie jetzt #include <winrt/Windows.Foundation.Collections.h>.
Der C++-Compiler erzeugt "Fehler C4002: Zu viele Argumente für funktionsähnlichen Makroaufruf GetCurrentTime". Siehe Wie kann ich Mehrdeutigkeiten mit GetCurrentTime und/oder TRY beheben?.
Der C++-Compiler erzeugt "Fehler C2334: unerwartetes Token(s) vor '{'; Überspringen des ersichtlichen Funktionskörpers". Siehe Wie kann ich Mehrdeutigkeiten mit GetCurrentTime und/oder TRY beheben?.
Der C++-Compiler erzeugt "winrt::impl::produce<D,I> kann keine abstrakte Klasse instanziieren, da GetBindingConnectorfehlt." Sie müssen #include <winrt/Windows.UI.Xaml.Markup.h>durchführen.
Der C++-Compiler erzeugt "Fehler C2039: 'promise_type': ist kein Element von 'std::experimental::coroutine_traits<void>'". Ihre Coroutine muss entweder ein asynchrones Vorgangsobjekt oder winrt::fire_and_forgetzurückgeben. Siehe Parallelität und asynchrone Vorgänge.
Ihr Projekt erzeugt "mehrdeutigen Zugriff auf 'PopulatePropertyInfoOverride'". Dieser Fehler kann auftreten, wenn Sie eine Basisklasse in Ihrer IDL und eine andere Basisklasse in Ihrem XAML-Markup deklarieren.
Das erstmalige Laden einer C++/WinRT-Lösung erzeugt "Entwurfszeit-Buildfehler für das Projekt 'MyProject.vcxproj', Konfiguration 'Debug|x86'. 'IntelliSense' ist möglicherweise nicht verfügbar.". Dieses IntelliSense-Problem wird nach der ersten Kompilierung behoben.
Beim Versuch, winrt::auto_revoke beim Registrieren eines Delegaten anzugeben, wird eine winrt::hresult_no_interface Ausnahme erzeugt. Siehe Wenn Ihre Stellvertretung für automatisches Widerrufennicht registriert.
In einer C++/WinRT-App erzeugt der Compiler bei der Nutzung einer C#-Windows-Runtime-Komponente, die XAML verwendet, einen Fehler der Form „'MyNamespace_XamlTypeInfo': ist kein Mitglied von 'winrt::MyNamespace'“, wobei MyNamespace der Name des Namespaces der Windows-Runtime-Komponente ist. Fügen Sie in pch.h der verbrauchenden C++/WinRT-App #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>hinzu und ersetzen Sie dabei durch MyNamespace.
In einem C++/WinRT-Projekt in Visual Studio erzeugt IntelliSense einen Fehler in der Form "Fehler E1696: Kann Quelldatei nicht öffnen". Kompilieren Sie das neu erstellte Projekt mindestens einmal. Klicken Sie dann mit der rechten Maustaste im Quellcode-Editor >Erneut scannen>Datei erneut scannen. Dadurch werden alle IntelliSense-Fehler behoben, einschließlich E1696.

Hinweis

Wenn dieses Thema Ihre Frage nicht beantwortet hat, finden Sie möglicherweise Hilfe, indem Sie die Visual Studio C++-Entwicklercommunitybesuchen oder das c++-winrt-Tag auf Stack Overflowverwenden.