Condividi tramite


Risoluzione dei problemi di C++/WinRT

Nota

Per informazioni sull'installazione e sull'uso dell'estensione per Visual Studio (VSIX) C++/WinRT, che fornisce il supporto per il modello di progetto, vedi Supporto di Visual Studio per C++/WinRT.

Questo argomento viene presentato in anticipo per consentirti di venirne a conoscenza subito, anche se ancora non ti serve. La seguente tabella di sintomi e rimedi per la risoluzione dei problemi può essere utile se devi creare nuovo codice o convertire un'app esistente. Se esegui la conversione, e vuoi procedere rapidamente al punto in cui il progetto viene compilato ed eseguito, puoi fare dei passi avanti temporanei impostando come commento o stub tutto il codice non essenziale che crea problemi, per poi tornare a sistemare i sospesi in un secondo momento.

Per un elenco delle domande più comuni, vedi Domande frequenti.

Individuazione dei problemi XAML

Le eccezioni di parsing XAML possono essere difficili da diagnosticare, soprattutto se non ci sono messaggi di errore significativi all'interno dell'eccezione. Assicurarsi che il debugger sia configurato per rilevare le eccezioni first-chance (per provare e intercettare l'eccezione di analisi all'inizio). È possibile esaminare la variabile di eccezione nel debugger per determinare se HRESULT o messaggio contiene informazioni utili. Controllare anche la finestra di output di Visual Studio per individuare i messaggi di errore restituiti dal parser XAML.

Se l'app si interrompe e tutto ciò che sai è che è stata generata un'eccezione non gestita durante l'analisi del markup XAML, questo potrebbe essere il risultato di un riferimento (per chiave) a una risorsa mancante. Potrebbe anche trattarsi di un'eccezione generata in un UserControl, in un controllo personalizzato o in un pannello di layout personalizzato. Un'ultima risorsa è una divisione binaria. Rimuovi metà del markup da una pagina XAML ed esegui di nuovo l'app. Scoprirai così se l'errore si trova all'interno della metà rimossa (che ora dovrai comunque ripristinare) o nella metà che non hai rimosso. Ripetere il processo suddividendo la metà che contiene l'errore e così via, fino a quando non si è azzerato nel problema.

Sintomi e rimedi

Sintomo Rimedio
Viene generata un'eccezione in fase di runtime con un valore HRESULT di REGDB_E_CLASSNOTREGISTERED. Vedi Per quale motivo viene restituita un'eccezione "classe non registrata"?.
Il compilatore C++ genera l'errore "'implements_type': is not a member of any direct or indirect base class of '<projected type>'" ("'tipo_implementazione': non è membro di alcuna classe di base diretta o indiretta di 'tipo proiettato'"). Questa situazione può verificarsi quando chiami make con il nome non qualificato dello spazio dei nomi del tuo tipo di implementazione (MyRuntimeClass, ad esempio) e non hai incluso l'intestazione di tale tipo. Il compilatore interpreta MyRuntimeClass come il tipo proiettato. La soluzione consiste nell'includere l'intestazione per il tipo di implementazione (MyRuntimeClass.h, ad esempio).
Il compilatore C++ genera l'errore "attempting to reference a deleted function" (tentativo di riferimento a una funzione eliminata). Questa situazione può verificarsi quando chiami make e il tipo di implementazione che passi come parametro del modello ha un costruttore predefinito = delete. Modifica il file di intestazione del tipo di implementazione e cambia = delete in = default. Inoltre, puoi aggiungere un costruttore in IDL per la classe di runtime.
Hai implementato INotifyPropertyChanged, ma i tuoi binding XAML non vengono aggiornati (e l'interfaccia utente non esegue la sottoscrizione a PropertyChanged). Ricorda di impostare Mode=OneWay (o TwoWay) sull'espressione di binding nel markup XAML. Vedi Controlli XAML, binding a una proprietà C++/WinRT.
Stai eseguendo il binding di un controllo di elementi XAML a una raccolta osservabile e viene generata un'eccezione in fase di runtime con messaggio che specifica che il parametro non è corretto. Nel file IDL e nell'implementazione dichiara qualsiasi raccolta osservabile come tipo Windows.Foundation.Collections.IVector<IInspectable>. Ma restituisci un oggetto che implementa Windows.Foundation.Collections.IObservableVector<T>, dove T è il tuo tipo di elemento. Vedi Controlli di elementi XAML, binding a una raccolta C++/WinRT.
Il compilatore C++ genera un errore nel formato "'MyImplementationType_base<MyImplementationType>': no appropriate default constructor available" ('MyImplementationType_base': non è disponibile alcun costruttore predefinito appropriato). Questo problema può verificarsi quando hai derivato da un tipo che ha un costruttore non semplice. Il costruttore del tipo derivato deve passare i parametri necessari al costruttore del tipo di base. Per un esempio elaborato, vedi Derivazione da un tipo che ha un costruttore non semplice.
Il C++ il compilatore genera l'errore "non possono convertire da ' const std:: Vector<std:: wstring, std:: allocator<Ty>>' a ' const winrt::param::async_iterable<winrt::hstring> &'". Ciò può verificarsi quando si passa un std::vector di std::wstring a un'API di Windows Runtime che prevede una raccolta. Per altre info, vedi Tipi di dati C++ standard e C++/WinRT.
Il C++ il compilatore genera l'errore "non possono convertire da ' const std:: Vector<winrt::hstring, std:: allocator<Ty>>' a ' const winrt::param::async_iterable<winrt::hstring> &'". Questa situazione può verificarsi quando passi un std::vector di winrt::hstring a un'API asincrona Windows Runtime che prevede una raccolta e non hai copiato né spostato il vettore nel computer chiamato asincrono. Per altre info, vedi Tipi di dati C++ standard e C++/WinRT.
Quando apri un progetto, Visual Studio genera l'errore "The application for the project is not installed" (L'applicazione del progetto non è installata). Se non lo hai già fatto, devi installare strumenti di Windows universale per lo sviluppo C++ dalla finestra di dialogo Nuovo progetto di Visual Studio. Se il problema persiste, il progetto può dipendere dall'estensione per Visual Studio (VSIX) C++/WinRT (vedi Supporto di Visual Studio per C++/WinRT).
I test del Kit di certificazione app Windows generano un errore che indica che una delle classi di runtime "non deriva da una classe di base di Windows. Tutte le classi componibili devono derivare da un tipo nello spazio dei nomi Windows". Qualsiasi classe di runtime (dichiarata all'interno dell'applicazione) che deriva da una classe di base è definita classe componibile. La classe di base finale di una classe componibile deve essere un tipo proveniente da uno spazio dei nomi Windows.*, ad esempio Windows.UI.Xaml.DependencyObject. Per altri dettagli, vedi Controlli XAML, binding a una proprietà C++/WinRT.
Il compilatore C++ genera un errore "T deve essere di tipo WinRT" per la specializzazione delegato EventHandler o TypedEventHandler. È consigliabile usare winrt::delegate<...T>. Vedi Creare eventi in C++/WinRT.
Il compilatore C++ genera un errore "T deve essere di tipo WinRT" per una specializzazione operazione asincrona Windows Runtime. Prendi in considerazione la restituzione di un'attività della libreria PPL (Parallel Patterns Library). Vedi Concorrenza e operazioni asincrone.
Il compilatore C++ genera un errore "T deve essere di tipo WinRT" quando si chiama winrt::xaml_typename. Usare il tipo proiettato con winrt::xaml_typename (ad esempio, usare BgLabelControlApp::BgLabelControl) e non il tipo di implementazione (ad esempio, non usare BgLabelControlApp::implementation::BgLabelControl). Vedere Controlli personalizzati XAML (basati su modelli).
Il compilatore C++ genera l'errore "C2220: warning treated as error - no 'object' file generated" (avviso considerato errore - Nessun file "oggetto" generato). Risolvi il problema o imposta C/C++>Generale>Considera gli avvisi come errori su No (/WX-).
L'app si arresta in modo anomalo poiché un gestore eventi nel tuo oggetto C++/WinRT viene chiamato dopo che l'oggetto è stato eliminato. Vedi Accesso sicuro al puntatore this con un delegato di gestione degli eventi.
Il compilatore C++ genera "errore C2338: questo è solo per il supporto di riferimento debole". Hai richiesto un riferimento debole per un tipo che ha passato lo struct dell'indicatore winrt::no_weak_ref come argomento di modello alla relativa classe base. Vedi Rifiuto esplicito del supporto di riferimenti deboli.
Il compilatore C++ produce "consume_Something: la funzione che restituisce 'auto' non può essere usata prima di essere definita" Vedere C3779: Perché il compilatore restituisce un errore "consume_Something: funzione che restituisce "auto" non può essere usata prima di essere definita?.
Il linker C++ genera"errore LNK2019: Unresolved external symbol Vedi Per quale motivo il linker restituisce un errore "LNK2019: Unresolved external symbol"?.
La toolchain LLVM/Clang genera errori se usata con C++/WinRT. La toolchain LLVM/Clang non è supportata per C++/WinRT. Se comunque vuoi emulare ciò che avviene internamente, puoi provare un esperimento come quello descritto in Posso usare LLVM/Clang per compilare con C++/WinRT?.
Il compilatore C++ genera un errore "no appropriate default constructor available" (non è disponibile alcun costruttore predefinito appropriato) per un tipo proiettato. Se stai tentando di ritardare l'inizializzazione di un oggetto di una classe di runtime oppure di utilizzare e implementare una classe di runtime nello stesso progetto, devi chiamare il costruttore std::nullptr_t. Per altre info, vedi Usare API con C++/WinRT.
Il compilatore C++ genera l'errore "C3861: 'from_abi': identifier not found" ('from_abi': identificatore non trovato) e altri errori con origine in base.h. Questo errore può verificarsi se si usa Visual Studio 2017 (versione 15.8.0 o successiva) e si seleziona come destinazione Windows SDK versione 10.0.17134.0 (Windows 10, versione 1803). La soluzione è selezionare una versione successiva (più conforme) di Windows SDK come destinazione oppure impostare la proprietà del progetto C/C++>Linguaggio>Modalità di conformità: No (elimina anche /permissive- se compare nella proprietà del progetto C/C++>Linguaggio>Riga di comando in Opzioni aggiuntive).
Il compilatore C++ genera "errore C2039: 'IUnknown': non è membro di ''global namespace''". Vedi Come impostare una versione più recente di Windows SDK come destinazione per il progetto C++/WinRT.
Se il linker C++ genera l'errore "error LNK2019: unresolved external symbol _WINRT_CanUnloadNow@0 referenced in function _VSDesignerCanUnloadNow@0" Vedi Come impostare una versione più recente di Windows SDK come destinazione per il progetto C++/WinRT.
Il processo di compilazione genera il messaggio di errore The C++/WinRT VSIX no longer provides project build support. Please add a project reference to the Microsoft.Windows.CppWinRT Nuget package (C++/WinRT VSIX non offre più il supporto per la compilazione dei progetti. Aggiungi un riferimento al progetto nel pacchetto NuGet Microsoft.Windows.CppWinRT). Installa il pacchetto NuGet Microsoft.Windows.CppWinRT nel progetto. Per informazioni dettagliate, vedi Versioni precedenti dell'estensione VSIX.
Il linker C++ genera l'errore LNK2019: unresolved external symbol (simbolo esterno non risolto) e viene menzionato winrt::impl::consume_Windows_Foundation_Collections_IVector. A partire da C++/WinRT 2.0, se usi un'istruzione for basata su intervallo in una raccolta di Windows Runtime, ora dovrai usare #include <winrt/Windows.Foundation.Collections.h>.
Quando si verifica un conflitto tra i due, il compilatore C++ genera l'errore "C4002: troppi argomenti per la chiamata 'GetCurrentTime' della macro simile a funzione". Vedi Come possono risolvere le ambiguità con GetCurrentTime e/o TRY?.
Il compilatore C++ genera l'errore "C2334: token imprevisti prima di '{'. Il corpo apparente della funzione verrà ignorato". Vedi Come possono risolvere le ambiguità con GetCurrentTime e/o TRY?.
Il compilatore C++ genera "winrt::impl::produce<D,I> cannot instantiate abstract class, due to missing GetBindingConnector" (Non è possibile creare un'istanza di classe astratta a causa di GetBindingConnector mancante). Devi specificare #include <winrt/Windows.UI.Xaml.Markup.h>.
Il compilatore C++ genera l'errore "error C2039: 'promise_type': non è un membro di 'std::experimental::coroutine_traits<void>'". Le coroutine deve restituire un oggetto operazione asincrona oppure winrt::fire_and_forget. Vedi Concorrenza e operazioni asincrone.
Il progetto genera l'errore "accesso ambiguo di 'PopulatePropertyInfoOverride'". Questo errore può verificarsi quando dichiari una classe di base nel codice IDL e un'altra classe di base nel markup XAML.
Quando una soluzione C++/WinRT viene caricata per la prima volta, viene generato "Designtime build failed for project 'MyProject.vcxproj' configuration 'Debug|x86'. IntelliSense potrebbe non essere disponibile". Dopo la prima compilazione, questo problema di IntelliSense verrà risolto.
Quando provi a specificare winrt::auto_revoke durante la registrazione di un delegato, viene generata un'eccezione winrt::hresult_no_interface. Vedi Se la registrazione del delegato di revoca automatica ha esito negativo.
In un'app C++/WinRT, quando viene usato un componente Windows Runtime C# che usa XAML, il compilatore genera un errore "'MyNamespace_XamlTypeInfo': non è un membro di 'winrt::MyNamespace'"dove MyNamespace è il nome dello spazio dei nomi del componente Windows Runtime. Nel file pch.h dell'app C++/WinRT consumer aggiungi #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>sostituendo MyNamespace in base alle esigenze.
In un progetto C++/WinRT in Visual Studio, IntelliSense genera un errore nel formato "errore E1696: impossibile aprire il file open source". Compilare almeno una volta il progetto appena creato. Fare quindi clic con il pulsante destro del mouse nell'editor del codice sorgente >Ripetere l'analisi>File di analisi. In questo modo verranno risolti tutti gli errori di IntelliSense, incluso E1696.

Nota

Se questo argomento non risponde alla domanda, potresti trovare assistenza visitando il sito della community degli sviluppatori Visual Studio C++ o tramite il tag c++-winrt in Stack Overflow.