Partilhar via


Solução de problemas de C++/WinRT

Observação

Para obter informações sobre como instalar e usar o C++/WinRT Visual Studio Extension (VSIX) (que fornece suporte a modelos de projeto), consulte Suporte do Visual Studio para C++/WinRT.

Este tópico está à frente para que esteja ciente dele imediatamente, mesmo que ainda não precise. A tabela de sintomas e soluções de problemas abaixo pode ser útil para você, quer você esteja cortando um novo código ou portando um aplicativo existente. Se você está fazendo a portabilidade e está ansioso para avançar e chegar ao estágio em que seu projeto é construído e executado, então você pode fazer um progresso temporário comentando ou cortando qualquer código não essencial que esteja causando problemas e, em seguida, retornando para pagar essa dívida mais tarde.

Para obter uma lista de perguntas frequentes, consulte Perguntas frequentes.

Rastreando problemas de XAML

As exceções de análise XAML podem ser difíceis de diagnosticar — particularmente se não houver mensagens de erro significativas dentro da exceção. Certifique-se de que o depurador está configurado para capturar exceções de primeira chance (para tentar capturar a exceção de análise logo no início). Talvez seja possível inspecionar a variável de exceção no depurador para determinar se o HRESULT ou a mensagem tem alguma informação útil. Além disso, verifique a janela de saída do Visual Studio para mensagens de erro saídas pelo analisador XAML.

Se seu aplicativo for encerrado e tudo o que você sabe é que uma exceção não tratada foi lançada durante a análise de marcação XAML, isso pode ser o resultado de uma referência (por chave) a um recurso ausente. Ou, pode ser uma exceção lançada dentro de um controle de usuário (UserControl), um controlo personalizado ou um painel de layout personalizado. Um último recurso é uma divisão binária. Remova cerca de metade da marcação de uma Página XAML e execute novamente o aplicativo. Você saberá então se o erro está em algum lugar dentro da metade que você removeu (que você deve restaurar agora em qualquer caso) ou na metade que você não removeu. Repita o processo dividindo a metade que contém o erro, e assim por diante, até zerar o problema.

Sintomas e remédios

Sintoma Solução
Uma exceção é lançada em tempo de execução com um valor HRESULT de REGDB_E_CLASSNOTREGISTERED. Veja Por que recebo uma exceção de "classe não registrada"?.
O compilador C++ produz o erro "'implements_type': não é um membro de qualquer classe base direta ou indireta de '<tipo projetado>'". Isso pode acontecer quando você invoca make com o nome não qualificado pelo espaço de nomes do seu tipo de implementação (MyRuntimeClass, por exemplo), e não incluiu o cabeçalho desse tipo. O compilador interpreta MyRuntimeClass como o tipo projetado. A solução é incluir o cabeçalho para o seu tipo de implementação (MyRuntimeClass.h, por exemplo).
O compilador C++ produz o erro "tentando fazer referência a uma função excluída". Isso pode acontecer quando você chama fazer e o tipo de implementação que você passa como o parâmetro de modelo tem um construtor padrão = delete. Edite o arquivo de cabeçalho do tipo de implementação e altere = delete para = default. Você também pode adicionar um construtor ao IDL para a classe runtime.
Você implementou INotifyPropertyChanged, mas as suas vinculações XAML não estão a ser atualizadas (e a interface do utilizador não está a inscrever-se em PropertyChanged). Lembre-se de definir Mode=OneWay (ou TwoWay) em sua expressão de vinculação na marcação XAML. Consulte os controlos XAML ; ligue a uma propriedade C++/WinRT.
Você está vinculando um controle de itens XAML a uma coleção observável e uma exceção é lançada em tempo de execução com a mensagem "O parâmetro está incorreto". Em seu IDL e sua implementação, declare qualquer coleção observável como o tipo Windows.Foundation.Collections.IVector<IInspectable>. Mas retorne um objeto que implementa Windows.Foundation.Collections.IObservableVector<T>, onde T é seu tipo de elemento. Consulte controles de itens XAML; vincular a uma coleção C++/WinRT.
O compilador C++ produz um erro do formato "'MyImplementationType_base<MyImplementationType>': nenhum construtor padrão apropriado disponível". Isto pode acontecer quando derivaste de um tipo que tem um construtor não trivial. O construtor do tipo derivado deve passar os parâmetros que o construtor do tipo base necessita. Para obter um exemplo trabalhado, consulte Derivando de um tipo que tem um construtor não trivial.
O compilador C++ produz o erro "cannot convert from 'const std::vector<std::wstring,std::allocator<_Ty>>' para 'const winrt::param::async_iterable<winrt::hstring> &'". Isso pode acontecer quando você passa um std::vector de std::wstring para uma Windows Runtime API que espera uma coleção. Para obter mais informações, consulte Tipos de dados C++ padrão e C++/WinRT.
O compilador C++ produz o erro "não é possível converter de 'const std::vector<winrt::hstring,std::allocator<_Ty>>' para 'const winrt::param::async_iterable<winrt::hstring> &'". Isso pode acontecer quando você passa um std::vetor de winrt::hstring para uma API assíncrona do Tempo de Execução do Windows que espera uma coleção e não copiou nem moveu o vetor para o destinatário assíncrono. Para obter mais informações, consulte Tipos de dados C++ padrão e C++/WinRT.
Ao abrir um projeto, o Visual Studio produz o erro "O aplicativo para o projeto não está instalado". Se ainda não o fez, terá de instalar ferramentas universais do Windows para desenvolvimento em C++ a partir da caixa de diálogo Novo Projeto do Visual Studio. Se isso não resolver o problema, o projeto pode depender da extensão C++/WinRT Visual Studio (VSIX) (consulte suporte do Visual Studio para C++/WinRT).
Os testes do Kit de Certificação de Aplicações Windows produzem um erro indicando que uma das suas classes de tempo de execução "não deriva de uma classe base do Windows. Todas as classes compostáveis devem, em última análise, derivar de um tipo no namespace do Windows". Qualquer classe de tempo de execução (que tu declaras na tua aplicação) que deriva de uma classe base é conhecida como uma classe composable. A classe base final de uma classe composable deve ser um tipo originário de um namespace Windows.*; por exemplo, Windows.UI.Xaml.DependencyObject. Veja controlos XAML; ligue a uma propriedade C++/WinRT para mais detalhes.
O compilador C++ produz um erro "T must be WinRT type" para uma especialização de delegado EventHandler ou TypedEventHandler. Considere usar winrt::delegate<...T> em vez disso. Consulte eventos Author em C++/WinRT.
O compilador C++ produz um erro "T must be WinRT type" para uma especialização de operação assíncrona do Windows Runtime. Em vez disso, considere retornar uma tarefa da Biblioteca de Padrões Paralelos (PPL) . Consulte Simultaneidade e operações assíncronas.
O compilador C++ produz um erro "T must be WinRT type" quando você chama winrt::xaml_typename. Use o tipo projetado com winrt::xaml_typename (por exemplo, use BgLabelControlApp::BgLabelControl), e não o tipo de implementação (por exemplo, não use BgLabelControlApp::implementation::BgLabelControl). Consulte controles personalizados (modelados) XAML.
O compilador C++ produz "erro C2220: aviso tratado como erro - nenhum ficheiro objeto gerado". Corrija o aviso ou defina C/C++>Geral>Tratar Avisos Como Erros como Não (/WX-).
Seu aplicativo falha porque um manipulador de eventos em seu objeto C++/WinRT é chamado depois que o objeto foi destruído. Consulte Acesso seguro ao este ponteiro com um delegado de manipulação de eventos.
O compilador C++ produz "erro C2338: Isto é apenas para suporte de referência fraca". Você está solicitando uma referência fraca para um tipo que passou o winrt::no_weak_ref marker struct como um argumento de modelo para sua classe base. Veja a exclusão do suporte a referências fracas.
O compilador C++ produz "consume_Something: função que retorna 'auto' não pode ser usada antes de ser definida" Veja C3779: Por que o compilador está me dando um erro "consume_Something: a função que retorna 'auto' não pode ser usada antes de ser definida"?.
O ligador C++ produz o erro LNK2019: "Símbolo externo não resolvido" Consulte Por que o vinculador está me dando um erro "LNK2019: símbolo externo não resolvido"?.
A cadeia de ferramentas LLVM e Clang produz erros quando usada com C++/WinRT. Não suportamos a cadeia de ferramentas LLVM e Clang para C++/WinRT, mas se você quiser emular como a usamos internamente, então você pode tentar um experimento como o descrito em Posso usar LLVM/Clang para compilar com C++/WinRT?.
O compilador C++ produz "nenhum construtor padrão apropriado disponível" para um tipo projetado. Se você estiver tentando atrasar a inicialização de um objeto de classe de tempo de execução ou consumir e implementar uma classe de tempo de execução no mesmo projeto, precisará chamar o construtor std::nullptr_t. Para obter mais informações, consulte Utilizar APIs com C++/WinRT.
O compilador C++ produz "erro C3861: 'from_abi': identificador não encontrado", e outros erros que se originam em base.h. Poderá ver este erro se estiver a utilizar o Visual Studio 2017 (versão 15.8.0 ou posterior) e a visar o SDK do Windows versão 10.0.17134.0 (Windows 10, versão 1803). Direcione uma versão posterior (mais conforme) do SDK do Windows ou defina a propriedade do projeto C/C++>Language>modo de conformidade: Sem (também, se /permissive- aparecer na propriedade do projeto C/C++>Language>Command Line em Opções Adicionais, em seguida, apague-o).
O compilador C++ produz "erro C2039: 'IUnknown': não é um membro do ''global namespace''". Consulte Como redirecionar seu projeto C++/WinRT para uma versão posterior do SDK do Windows.
O vinculador C++ produz LNK2019 de erro ": símbolo externo não resolvido _WINRT_CanUnloadNow@0 referenciado na função _VSDesignerCanUnloadNow@0" Consulte Como redirecionar seu projeto C++/WinRT para uma versão posterior do SDK do Windows.
O processo de compilação produz a mensagem de erro O C++/WinRT VSIX não fornece mais suporte à compilação do projeto. Adicione uma referência de projeto ao pacote Nuget Microsoft.Windows.CppWinRT. Instale o pacote Microsoft.Windows.CppWinRT NuGet em seu projeto. Para obter detalhes, consulte Versões anteriores da extensão VSIX.
O vinculador C++ produz LNK2019 de erro: símbolo externo não resolvido, com uma menção de winrt::impl::consume_Windows_Foundation_Collections_IVector. A partir de C++/WinRT 2.0, se estiver a usar um for baseado em intervalos numa coleção do Ambiente de Execução Windows, precisará de #include <winrt/Windows.Foundation.Collections.h>.
O compilador C++ produz "erro C4002: Argumentos em excesso para invocação de macro semelhante a função GetCurrentTime". Consulte Como resolvo ambiguidades com GetCurrentTime e/ou TRY?.
O compilador C++ produz "erro C2334: símbolos inesperados precedendo '{'; ignorando o corpo de função aparente". Consulte Como resolvo ambiguidades com GetCurrentTime e/ou TRY?.
O compilador C++ produz "winrt::impl::produce<D,I> não pode instanciar a classe abstrata, devido à falta de GetBindingConnector". Você precisa fazer #include <winrt/Windows.UI.Xaml.Markup.h>.
O compilador C++ produz "erro C2039: 'promise_type': não é um membro de 'std::experimental::coroutine_traits<void>'". A sua co-rotina precisa retornar um objeto de operação assíncrona ou winrt::fire_and_forget. Consulte Simultaneidade e operações assíncronas.
O seu projeto produz "acesso ambíguo do 'PopulatePropertyInfoOverride'". Esse erro pode ocorrer quando você declara uma classe base em seu IDL e uma classe base diferente em sua marcação XAML.
Ao carregar uma solução C++/WinRT pela primeira vez, surge o erro "Falha na compilação em tempo de design para o projeto 'MyProject.vcxproj' na configuração 'Debug|x86'. O IntelliSense pode não estar disponível.". Este problema do IntelliSense será resolvido após a primeira compilação.
A tentativa de especificar winrt::auto_revoke ao inscrever um delegado produz uma exceção winrt::hresult_no_interface. Consulte se o seu delegado de revogação automática não conseguir registar-se em.
Em um aplicativo C++/WinRT, ao consumir um componente C# do Tempo de Execução do Windows que usa XAML, o compilador produz um erro do formato "'MyNamespace_XamlTypeInfo': não é membro de 'winrt::MyNamespace'"— onde MyNamespace é o nome do namespace do componente do Tempo de Execução do Windows. No aplicativo C++/WinRT que está a consumir, em pch.h, adicione #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>— substituindo MyNamespace conforme apropriado.
Em um projeto C++/WinRT no Visual Studio, IntelliSense produz um erro do formato "erro E1696: não é possível abrir o arquivo de origem". Compile seu projeto recém-criado pelo menos uma vez. Em seguida, clique com o botão direito do mouse no editor de código-fonte >Rescan>Rescan File. Isso resolverá todos os erros do IntelliSense, incluindo o E1696.

Observação

Se este tópico não responder à sua pergunta, você pode encontrar ajuda visitando a comunidade de desenvolvedores do Visual Studio C++ ou usando a marca c++-winrt em Stack Overflow.