Freigeben über


Behandlung von C++/WinRT-Problemen

Hinweis

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

Dieses Thema stellt vorsorglich Informationen zur Verfügung. Sie sollten diese kennen, auch wenn Sie sie noch nicht unmittelbar benötigen. Die Tabelle mit den Symptomen und Lösungen unten kann für Sie hilfreich sein, gleich ob Sie neuen Code schreiben oder eine bestehende Anwendung portieren. Wenn Sie beim Portieren vorankommen und an den Punkt gelangen möchten, an dem Ihr Projekt erstellt und ausgeführt werden kann, können Sie vorübergehend Fortschritte machen, indem Sie allen nicht zwingend erforderlichen Code, der Probleme verursacht, auskommentieren oder streichen. Sie können zu einem späteren Zeitpunkt zurückkehren und Ihren Rückstand abarbeiten.

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

Ermitteln von XAML-Problemen

XAML-Analyseausnahmen sind u U. schwierig zu diagnostizieren, insbesondere wenn keine sinnvollen Fehlermeldungen innerhalb der Ausnahme vorhanden sind. Stellen Sie sicher, dass der Debugger für die Erfassung von Ausnahmen (erste Chance) konfiguriert ist (um die Analyseausnahme möglichst früh zu erfassen). Möglicherweise können Sie die Ausnahmevariable im Debugger überprüfen, um zu ermitteln, ob das HRESULT oder die Meldung hilfreiche Informationen enthält. Überprüfen Sie auch das Visual Studio-Ausgabefenster auf Fehlermeldungen des XAML-Parsers.

Wenn Ihre App beendet wird und Sie nur wissen, dass beim XAML-Markup-Parsing eine unbehandelte Ausnahme ausgelöst wurde, dann könnte das das Ergebnis eines Verweises (anhand des Schlüssels) auf eine fehlende Ressource sein. Es kann sich auch um eine Ausnahme handeln, die innerhalb eines UserControl-Elements, eines benutzerdefinierten Steuerelements oder eines benutzerdefinierten Layoutpanels ausgelöst wurde. Als letzte Möglichkeit kann eine Binärdatei aufgeteilt werden. Entfernen Sie etwa die Hälfte des Markups von einer XAML-Seite, und führen Sie die App erneut aus. So können Sie feststellen, ob sich der Fehler in der entfernten Hälfte (die Sie jetzt in jedem Fall wiederherstellen sollten) oder in der nicht entfernten Hälfte befindet. Wiederholen Sie den Vorgang durch Teilen der Hälfte mit den Fehler solange, Sie das Problem eingegrenzt haben.

Symptome und Lösungen

Symptom Problembehandlung
Zur Laufzeit wird eine Ausnahme mit dem HRESULT-Wert REGDB_E_CLASSNOTREGISTERED ausgelöst. Siehe Warum erhalte ich die Ausnahme „Klasse nicht registriert“?.
Der C++ Compiler erzeugt den Fehler „‚implements_type‘: ist kein Mitglied einer direkten oder indirekten Basisklasse von ‚<projizierter Typ>‘“. Dies kann passieren, wenn Sie make mit dem nicht im Namespace qualifizierten Namen Ihres Implementierungstyps (z.B. MyRuntimeClass) aufrufen und den Header dieses Typs nicht eingebunden haben. Der Compiler interpretiert MyRuntimeClass als den projizierten Typ. Die Lösung besteht darin, den Header für Ihren Implementierungstyp (z.B. MyRuntimeClass.h) einzubinden.
Der C++ Compiler erzeugt den Fehler „Versuch, auf eine gelöschte Funktion zu verweisen“. Dies kann passieren, wenn Sie make aufrufen und der Implementierungstyp, den Sie als Vorlagenparameter übergeben, einen = delete-Standardkonstruktor hat. Bearbeiten Sie die Header-Datei des Implementierungstyps, und ändern Sie = delete in = default. Sie können auch einen Konstruktor in die IDL für die Laufzeitklasse einfügen.
Sie haben INotifyPropertyChanged implementiert, aber Ihre XAML-Bindungen werden nicht aktualisiert (und die Benutzeroberfläche registriert sich nicht für PropertyChanged). Denken Sie daran, Mode=OneWay (oder TwoWay) für Ihren Bindungsausdruck im XAML-Markup festzulegen. Weitere Informationen finden Sie unter XAML-Steuerelemente; Binden an eine C++/WinRT-Eigenschaft.
Sie binden ein XAML-Items-Steuerelement an eine Observable-Sammlung, und zur Laufzeit wird eine Ausnahme mit der Meldung „Der Parameter ist falsch“ ausgelöst. Deklarieren Sie in Ihrer IDL und Ihrer Implementierung jede Observable-Sammlung als Typ Windows.Foundation.Collections.IVector<IInspectable>. Geben Sie jedoch ein Objekt zurück, das Windows.Foundation.Collections.IObservableVector<T> implementiert, wobei T Ihr Elementtyp ist. Weitere Informationen finden Sie unter XAML-Items-Steuerelemente; Binden an eine C++/WinRT-Collection.
Der C++ Compiler erzeugt einen Fehler der Form „‚MyImplementationType_base<MyImplementationType>‘: kein passender Standardkonstruktor verfügbar“. Dies kann passieren, wenn Sie von einem Typ abgeleitet haben, der einen nicht-trivialen Konstruktor hat. Der Konstruktor Ihres abgeleiteten Typs muss die Parameter übergeben, die der Konstruktor des Basistyps benötigt. Ein funktionierendes Beispiel finden Sie unter Ableiten von einem Typ, der einen nicht trivialen Konstruktor hat.
Der C++ Compiler erzeugt den Fehler „Konvertierung von ‚const std::vector<std::wstring,std::allocator<_Ty>>‘ zu ‚const winrt::param::async_iterable<winrt::hstring> &‘ nicht möglich“. Dies kann passieren, wenn Sie einen std::vector vom Typ 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 „Konvertierung von ‚const std::vector<winrt::hstring,std::allocator<_Ty>>‘ zu „const winrt::param::async_iterable<winrt::hstring> &‘ nicht möglich“. Dies kann passieren, wenn Sie einen std::vector vom Typ winrt::hstring an eine asynchrone Windows Runtime-API übergeben, die eine Sammlung erwartet, und Sie den Vektor zum asynchronen Aufrufer weder kopiert noch verschoben 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 ist nicht installiert“. Falls noch nicht geschehen, müssen Sie im Dialogfeld Neues Projekt von Visual Studio Universelle Windows-Tools für die C++-Entwicklung installieren. Wenn das Problem dadurch nicht behoben wird, hängt das Projekt möglicherweise von der C++/WinRT Visual Studio Extension (VSIX) ab (siehe Visual Studio-Unterstützung für C++/WinRT).
Die Tests im Zertifizierungskit für Windows-Apps erzeugen einen Fehler, dass eine Ihrer Laufzeitklassen „ist nicht von einer Windows-Basisklasse abgeleitet. Alle zusammensetzbaren Klassen müssen letztlich von einem Typ im Windows-Namespace abgeleitet sein“. Jede Laufzeitklasse (die Sie in Ihrer Anwendung deklarieren), die von einer Basisklasse abgeleitet ist, wird als zusammensetzbare Klasse bezeichnet. Die letztliche Basisklasse einer zusammensetzbaren Klasse muss ein Typ sein, der seinen Ursprung in einem Windows.*-Namespace hat; beispielsweise Windows.UI.Xaml.DependencyObject. Weitere Details finden Sie unter XAML-Steuerelemente; Binden an eine C++/WinRT-Eigenschaft.
Der C++-Compiler erzeugt einen Fehler, der darauf hinweist, dass T ein WinRT-Typ sein muss, für eine EventHandler- oder TypedEventHandler-Delegatspezialisierung. Erwägen Sie stattdessen die Verwendung von winrt::delegate<...T>. Mehr dazu erfahren Sie unter Erstellen von Ereignissen in C++/WinRT.
Der C++-Compiler erzeugt einen Fehler, der darauf hinweist, dass T ein WinRT-Typ sein muss, für eine Spezialisierung eines asynchronen Vorgangs von Windows-Runtime. Erwägen Sie, stattdessen eine Aufgabe der Parallel Patterns Library (PPL) zurückzugeben. Mehr dazu erfahren Sie unter Parallelität und asynchrone Vorgänge.
Der C++ Compiler erzeugt einen Fehler, der darauf hinweist, dass T ein WinRT-Typ sein muss, wenn Sie winrt::xaml_typename aufrufen. Verwenden Sie den projizierten Typ mit winrt::xaml_typename (z. B. BgLabelControlApp::BgLabelControl), und nicht den Implementierungstyp (z. B. nicht BgLabelControlApp::implementation::BgLabelControl). Siehe XAML-Steuerelemente, benutzerdefinierte Vorlagen.
Der C++ Compiler erzeugt „Fehler C2220: Warnung als Fehler behandelt – keine ‚Object‘-Datei generiert“. Korrigiere entweder die Warnung, oder lege C/C++>Allgemein>Warnung als Fehler behandeln auf Nein (/WX-) fest.
Ihre App stürzt ab, weil ein Ereignishandler in Ihrem C++/WinRT-Objekt aufgerufen wird, nachdem das Objekt zerstört wurde. Weitere Informationen dazu finden Sie unter Sicherer Zugriff auf den this-Zeiger mit einer Stellvertretung zum Ereignishandling
Der C++-Compiler erzeugt „Fehler C2338: Dies dient nur zur Unterstützung schwacher Verweise“. Sie fordern einen schwachen Verweis für einen Typ an, der die winrt::no_weak_ref-Markerstruktur als Vorlagenargument an seine Basisklasse übergeben hat. Mehr dazu finden Sie unter Verzicht auf die Unterstützung von schwachen Verweisen.
Der C++-Compiler erzeugt den Fehler „consume_Something: Eine Funktion, die ‚auto‘ zurückgibt, darf nicht verwendet werden, bevor sie definiert ist Siehe C3779: Warum zeigt der Compiler den Fehler „consume_Something: Eine Funktion, die ‚auto‘ zurückgibt, darf nicht verwendet werden, bevor sie definiert ist“ an?
Der C++-Linker erzeugt „Fehler LNK2019: Nicht aufgelöstes externes Symbol Mehr dazu finden Sie unter Warum erhalte ich den Fehler „LNK2019: Nicht aufgelöstes externes Symbol“ vom Linker?.
Die LLVM- und Clang-Toolkette führt bei der Verwendung mit C++/WinRT zu Fehlern. Wir unterstützen die LLVM- und Clang-Toolkette für C++/WinRT nicht, aber wenn Sie die interne Verwendung durch uns emulieren wollten, können Sie ein Experiment wie das in Kann ich LLVM/Clang für die Kompilierung mit C++/WinRT verwenden? beschriebene ausprobieren.
Der C++-Compiler erzeugt „kein passender Standardkonstruktor verfügbar“ für einen projizierten Typ. Wenn Sie versuchen, die Initialisierung eines Laufzeitklassenobjekts zu verzögern, oder eine Laufzeitklasse im gleichen 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 aus base.h stammen. Möglicherweise sehen Sie diesen Fehler, wenn Sie Visual Studio 2017 (Version 15.8.0 oder höher) verwenden und die Windows SDK-Version 10.0.17134.0 (Windows 10, Version 1803) als Ziel festgelegt haben. Verwenden Sie für das Projekt entweder eine höhere (konformere) Version des Windows SDK oder die Projekteigenschaft C/C++>Sprache>Konformitätsmodus: Nein (auch wenn /permissive- in der Projekteigenschaft C/C++>Sprache>Befehlszeile unter Zusätzliche Optionen angezeigt wird. Löschen Sie es dann).
Der C++-Compiler erzeugt „Fehler C2039: "IUnknown" ist kein Member von "global namespace"“. Lesen Sie So richten Sie Ihr C++/WinRT-Projekt auf eine höhere Version des Windows SDK neu aus.
Der C++-Linker erzeugt den Fehler „Fehler LNK2019: Verweis auf nicht aufgelöstes externes Symbol _WINRT_CanUnloadNow@0 in Funktion _VSDesignerCanUnloadNow@0“. Lesen Sie So richten Sie Ihr C++/WinRT-Projekt auf eine höhere Version des Windows SDK neu aus.
Der Buildprozess erzeugt die Fehlermeldung C++/WinRT VSIX bietet keine Projekbuildunterstützung mehr. Fügen Sie dem Nuget-Paket „Microsoft.Windows.CppWinRT“ einen Projektverweis hinzu. Installieren Sie das NuGet-Paket Microsoft.Windows.CppWinRT für Ihr Projekt. Ausführlichere Informationen finden Sie unter Frühere Versionen der VSIX-Erweiterung.
Der C++-Linker erzeugt Fehler LNK2019: nicht aufgelöstes externes Symbol mit einer Erwähnung von winrt::impl::consume_Windows_Foundation_Collections_IVector. Wenn Sie seit C++/WinRT 2.0 ein bereichsbasiertes for in einer Windows Runtime-Sammlung verwenden, müssen Sie jetzt #include <winrt/Windows.Foundation.Collections.h> ausführen.
Der C++-Compiler erzeugt „Fehler C4002: Zu viele Argumente für den Aufruf des funktionsähnlichen Makros "GetCurrentTime“. Siehe Wie löse ich Mehrdeutigkeiten bei „GetCurrentTime“ und/oder „TRY“ auf?.
Der C++-Compiler erzeugt „Fehler C2334: Unerwartete(s) Token vor "{"; sichtbarer Funktionstext wird übersprungen“. Siehe Wie löse ich Mehrdeutigkeiten bei „GetCurrentTime“ und/oder „TRY“ auf?.
Der C++-Compiler erzeugt „winrt::impl::produce<D,I>: Instanz von abstrakter Klasse kann nicht erstellt werden, da "GetBindingConnector" nicht vorhanden ist“. Sie müssen #include <winrt/Windows.UI.Xaml.Markup.h> hinzufügen.
Der C++-Compiler erzeugt „Fehler C2039: "promise_type" ist kein Member von "std::experimental::coroutine_traits<void>"“. Die Coroutine muss ein Objekt eines asynchronen Vorgangs oder winrt::fire_and_forget zurückgeben. Mehr dazu erfahren Sie unter Parallelität und asynchrone Vorgänge.
Im Projekt wird „Mehrdeutiger Zugriff von"PopulatePropertyInfoOverride"“ ausgelöst. Dieser Fehler kann auftreten, wenn Sie eine Basisklasse in der IDL und eine andere Basisklasse im XAML-Markup deklarieren.
Beim ersten Laden einer C++/WinRT-Projektmappe wird „Fehler beim Entwurfszeitbuild für das Projekt "MyProject.vcxproj", Konfiguration "Debug|x 86". IntelliSense ist möglicherweise nicht verfügbar.“. Dieses IntelliSense-Problem ist nach dem ersten Buildvorgang nicht mehr vorhanden.
Wenn beim Registrieren eines Delegaten winrt::auto_revoke angegeben wird, wird die Ausnahme winrt::hresult_no_interface erzeugt. Siehe Wenn das Registrieren des Delegaten fehlschlägt.
Wenn in einer C++/WinRT-App eine C#-Komponente für Windows-Runtime, die XAML verwendet, verarbeitet wird, erzeugt der Compiler einen Fehler der Form „'MyNamespace_XamlTypeInfo': is not a member of 'winrt::MyNamespace'“, wobei MyNamespace der Name des Namespace der Windows Runtime-Komponente ist. Fügen Sie in pch.h in der verarbeitenden C++/WinRT-App #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h> hinzu, und ersetzen Sie MyNamespace entsprechend.
In einem C++/WinRT-Projekt in Visual Studio verursacht IntelliSense einen Fehler wie Fehler E1696: Quelldatei kann nicht geöffnet werden. Kompilieren Sie Ihr neu erstelltes Projekt mindestens einmal. Klicken Sie dann im Quellcode-Editor mit der rechten Maustaste, und wählen Sie Neu einlesen>Datei neu einlesen aus. Dadurch werden alle IntelliSense-Fehler behoben, einschließlich E1696.

Hinweis

Wenn Ihre Frage in diesem Thema nicht beantwortet wurde, finden Sie möglicherweise Hilfe in der Visual Studio C++-Entwicklercommunity, oder verwenden Sie das c++-winrt-Tag auf Stack Overflow.