Condividi tramite


Risoluzione dei problemi di C++/WinRT

Annotazioni

Per informazioni sull'installazione e l'uso dell'estensione di Visual Studio (VSIX) C++/WinRT, che fornisce supporto per i modelli di progetto, vedere il supporto di Visual Studio per C++/WinRT .

Questo argomento è in primo piano in modo che tu ne sia a conoscenza subito; anche se non ne hai ancora bisogno. La tabella dei sintomi e dei rimedi per la risoluzione dei problemi riportati di seguito può essere utile se si taglia nuovo codice o si esegue la conversione di un'app esistente. Se stai effettuando il porting e sei desideroso di proseguire e passare alla fase in cui il progetto viene compilato ed eseguito, puoi fare progressi temporanei commentando o stubando qualsiasi codice non essenziale che causa problemi e quindi tornando a pagare il debito in un secondo momento.

Per un elenco delle domande frequenti, vedere domande frequenti.

Rilevamento dei problemi XAML

Le eccezioni di analisi XAML possono essere difficili da diagnosticare, in particolare se non sono presenti messaggi di errore significativi all'interno dell'eccezione. Assicurarsi che il debugger sia configurato per rilevare le eccezioni alla prima occorrenza (per tentare e intercettare precocemente l'eccezione di analisi). È 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 termina e tutto quello 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. In alternativa, potrebbe trattarsi di un'eccezione generata all'interno di un controllo UserControl, di un controllo personalizzato o di un pannello di layout personalizzato. Un'ultima risorsa è una divisione binaria. Rimuovere circa la metà del markup da una pagina XAML ed eseguire nuovamente l'app. Saprai quindi se l'errore è da qualche parte all'interno della metà che hai rimosso (che dovresti ora ripristinare in ogni caso) o nella metà che non hai rimosso. Ripetere il processo suddividendo la metà che contiene l'errore e così via, fino a identificare il problema.

Sintomi e rimedi

Sintomo Rimedio
Viene generata un'eccezione in fase di esecuzione con un valore HRESULT di REGDB_E_CLASSNOTREGISTERED. Consulta Perché viene visualizzata un'eccezione "classe non registrata"?.
Il compilatore C++ genera l'errore "'implements_type': non è membro di alcuna classe base diretta o indiretta di '<tipo proiettato>'". Ciò può verificarsi quando si chiama make con il nome non qualificato dello spazio dei nomi del tipo di implementazione (MyRuntimeClass, ad esempio) e non è stata inclusa l'intestazione del tipo. Il compilatore interpreta MyRuntimeClass come tipo proiettato. La soluzione consiste nell'includere l'intestazione per il tipo di implementazione ( ad esempioMyRuntimeClass.h).
Il compilatore C++ genera l'errore "tentativo di fare riferimento a una funzione eliminata". Ciò può verificarsi quando si chiama make e il tipo di implementazione passato come parametro template ha un = delete costruttore predefinito. Modifica l'intestazione del file del tipo di implementazione e sostituisci = delete con = default. È anche possibile aggiungere un costruttore nel file IDL per la classe di runtime.
Hai implementato INotifyPropertyChanged, ma le associazioni XAML non vengono aggiornate e l'interfaccia utente non sottoscrive PropertyChanged. Ricorda di assegnare Mode=OneWay (o TwoWay) nell'espressione di binding nel markup XAML. Vedi controlli XAML; associa a una proprietà C++/WinRT.
Si sta associando un controllo elementi XAML a una raccolta osservabile e viene generata un'eccezione in fase di esecuzione con il messaggio "Il parametro non è corretto". Nell'IDL e nell'implementazione dichiarare qualsiasi raccolta osservabile come tipo Windows.Foundation.Collections.IVector<IInspectable>. Tuttavia, restitui un oggetto che implementa Windows.Foundation.Collections.IObservableVector<T>, dove T è il tipo di elemento. Vedi controlli elementi XAML; eseguire l'associazione a una raccolta C++/WinRT.
Il compilatore C++ genera un errore nel formato "'MyImplementationType_base<MyImplementationType>': nessun costruttore predefinito appropriato disponibile". Ciò può verificarsi quando hai derivato da un tipo con un costruttore non banale. Il costruttore del tipo derivato deve passare i parametri necessari al costruttore del tipo di base. Per un esempio pratico, vedere Derivare da un tipo che ha un costruttore non banale.
Il compilatore C++ genera l'errore "cannot convert from 'const std::vector<std::wstring,std::allocator<_Ty>>' to 'const winrt::param::async_iterable<winrt::hstring> &'". Ciò può verificarsi quando passi un std::vector di std::wstring a un'API di Windows Runtime che prevede una raccolta. Per ulteriori informazioni, vedi Tipi di dati Standard C++ e C++/WinRT.
Il compilatore C++ genera l'errore "cannot convert from 'const std::vector<winrt::hstring,std::allocator<_Ty>>' to 'const winrt::param::async_iterable<winrt::hstring> &'". Ciò può verificarsi quando passi un std::vector di winrt::hstring a un'API di Windows Runtime asincrona che si aspetta una raccolta e non hai copiato né spostato il vettore al destinatario asincrono. Per ulteriori informazioni, vedi Tipi di dati Standard C++ e C++/WinRT.
Quando si apre un progetto, Visual Studio genera l'errore "L'applicazione per il progetto non è installata". Se non è già stato fatto, è necessario installare strumenti universali di Windows per lo sviluppo C++ dall'interno della finestra di dialogo Nuovo progetto di Visual Studio. Se il problema non viene risolto, il progetto può dipendere dall'estensione di Visual Studio C++/WinRT (VSIX) (vedere supporto di Visual Studio per C++/WinRT.
I test del Kit di certificazione app Windows generano un errore indicando 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 nell'applicazione) che deriva da una classe di base è nota come classe componibile. La classe base finale di una classe componibile deve essere un tipo che ha origine in uno spazio dei nomi Windows.*; ad esempio Windows.UI.Xaml.DependencyObject. Vedi i controlli XAML e associa a una proprietà C++/WinRT per ulteriori dettagli.
Il compilatore C++ produce un errore "T deve essere di tipo WinRT" per una specializzazione del tipo delegato EventHandler o TypedEventHandler. È consigliabile usare winrt::delegate<...T>. Consulta Eventi dell'autore in C++/WinRT.
Il compilatore C++ produce un errore "T deve essere di tipo WinRT" per una specializzazione di operazione asincrona di Windows Runtime. Considerare di restituire un'attività della PPL (Parallel Patterns Library) . Vedere 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). Vedi controlli xaml personalizzati (basati su modelli).
Il compilatore C++ genera "errore C2220: avviso trattato come errore - nessun file 'object' generato". Correggere l'avviso o impostare C/C++>Generale>Considera gli avvisi come errori su No (/WX-).
L'app si arresta in modo anomalo perché un gestore eventi nell'oggetto C++/WinRT viene chiamato dopo che l'oggetto è stato distrutto. Vedere Accesso sicuro alla questo puntatore con un delegato di gestione degli eventi.
Il compilatore C++ produce "errore C2338: questo è solo per il supporto di riferimento debole". Stai richiedendo un riferimento debole per un tipo che ha passato lo struct del marcatore winrt::no_weak_ref come argomento di modello alla sua classe base. Vedere rifiutare esplicitamente il supporto di riferimenti deboli.
Il compilatore C++ genera "consume_Something: una funzione che restituisce 'auto' non può essere utilizzata prima di essere definita" Consulta C3779: Perché il compilatore restituisce un errore "consume_Something: funzione che restituisce 'auto' non può essere utilizzata prima di essere definita"?.
Il linker C++ genera "errore LNK2019: simbolo esterno non risolto" Consulta Perché il linker mi dà un errore "LNK2019: Simbolo esterno non risolto"?.
La toolchain LLVM e Clang genera errori quando viene utilizzata con C++/WinRT. Non è supportata la toolchain LLVM e Clang per C++/WinRT, ma se si vuole emulare il modo in cui viene usata internamente, è possibile provare un esperimento come quello descritto in È possibile usare LLVM/Clang per compilare con C++/WinRT?.
Il compilatore C++ produce "nessun costruttore predefinito appropriato disponibile" per un tipo proiettato. Se si sta tentando di ritardare l'inizializzazione di un oggetto classe di runtime o di utilizzare e implementare una classe di runtime nello stesso progetto, sarà necessario chiamare il costruttore std::nullptr_t. Per ulteriori informazioni, vedi Utilizzare API con C++/WinRT.
Il compilatore C++ genera l'errore "errore C3861: 'from_abi': identificatore non trovato" e altri errori che hanno origine in base.h. Questo errore può verificarsi se si usa Visual Studio 2017 (versione 15.8.0 o successiva) e si usa Windows SDK versione 10.0.17134.0 (Windows 10, versione 1803). Scegliere come destinazione una versione successiva (più conforme) di Windows SDK o impostare la proprietà del progetto Linguaggio C/C++>>Modalità di conformità: No (anche se /permissive- compare nella proprietà del progetto C/C++>Linguaggio>riga di comando sotto Opzioni aggiuntive, quindi eliminarlo).
Il compilatore C++ genera "errore C2039: 'IUnknown': non è un membro di '`global namespace''". Vedi Come ridestinare il progetto C++/WinRT in una versione successiva di Windows SDK.
Il linker C++ produce "errore LNK2019: simbolo esterno non risolto _WINRT_CanUnloadNow@0 a cui viene fatto riferimento nella funzione _VSDesignerCanUnloadNow@0" Vedi Come ridestinare il progetto C++/WinRT in una versione successiva di Windows SDK.
Il processo di compilazione genera il messaggio di errore C++/WinRT VSIX non fornisce più il supporto per la compilazione del progetto. Aggiungere un riferimento al progetto al pacchetto NuGet Microsoft.Windows.CppWinRT. Installare il pacchetto NuGet Microsoft.Windows.CppWinRT nel progetto. Per informazioni dettagliate, vedere le versioni precedenti dell'estensione VSIX .
Il linker C++ genera l'errore LNK2019: simbolo esterno non risolto, con riferimento a winrt::impl::consume_Windows_Foundation_Collections_IVector. A partire da C++/WinRT 2.0, Se usi un for basato su intervalli in una raccolta di Windows Runtime, dovrai ora #include <winrt/Windows.Foundation.Collections.h>.
Il compilatore C++ produce "errore C4002: Troppi argomenti per la chiamata di macro di tipo funzione GetCurrentTime". Consulta Come risolvere le ambiguità con GetCurrentTime e/o TRY?.
Il compilatore C++ genera "errore C2334: token imprevisti precedenti '{'; ignorando l'apparente corpo della funzione". Consulta Come risolvere le ambiguità con GetCurrentTime e/o TRY?.
Il compilatore C++ produce "winrt::impl::produce<D,I> non può creare un'istanza di classe astratta, a causa di GetBindingConnector mancante". È necessario #include <winrt/Windows.UI.Xaml.Markup.h>.
Il compilatore C++ genera l'errore "errore C2039: 'promise_type': non è membro di 'std::experimental::coroutine_traits<void>'". La tua coroutine deve restituire un oggetto di operazione asincrona oppure winrt::fire_and_forget. Vedere concorrenza e operazioni asincrone.
Il tuo progetto produce un "accesso ambiguo di 'PopulatePropertyInfoOverride'". Questo errore può verificarsi quando dichiari una classe di base nel codice IDL e una classe base diversa nel markup XAML.
Il caricamento di una soluzione C++/WinRT per la prima volta produce "compilazione in fase di progettazione non riuscita per il progetto 'MyProject.vcxproj' nella configurazione 'Debug|x86'. IntelliSense potrebbe non essere disponibile.". Questo problema di IntelliSense verrà risolto dopo aver compilato per la prima volta.
Il tentativo di specificare winrt::auto_revoke durante la registrazione di un delegato genera un'eccezione winrt::hresult_no_interface. Consultare se il delegato di revoca automatica non riesce a registrare.
In un'applicazione C++/WinRT, quando si utilizza un componente Windows Runtime C# che usa XAML, il compilatore genera un errore del tipo "'MyNamespace_XamlTypeInfo': non è membro di 'winrt::MyNamespace'"—in cui MyNamespace è il nome dello spazio dei nomi del componente Windows Runtime. In pch.h nell'app C++/WinRT consumatrice aggiungere #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. Quindi fare clic con il pulsante destro del mouse nell'editor del codice sorgente >Ripetere l'analisi>Ripetere l'analisi del file. In questo modo verranno risolti tutti gli errori di IntelliSense, incluso E1696.

Annotazioni

Se questo argomento non ha risposto alla domanda, è possibile trovare assistenza visitando la community di sviluppatori di Visual Studio C++ oppure usando il tag c++-winrt in Stack Overflow.