Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
À medida que as versões subsequentes do C++/WinRT são lançadas, este tópico descreve as novidades e o que mudou.
Resumo das melhorias e adições recentes até março de 2020
Tempos de build até 23% menores
As equipes do compilador C++/WinRT e C++ colaboraram para fazer todo o possível para reduzir os tempos de build. Analisamos a análise do compilador para descobrir como os internos do C++/WinRT podem ser reestruturados para ajudar o compilador C++ a eliminar a sobrecarga de tempo de compilação, bem como como o próprio compilador C++ pode ser aprimorado para lidar com a biblioteca C++/WinRT. O C++/WinRT foi otimizado para o compilador; e o compilador foi otimizado para C++/WinRT.
Vejamos, por exemplo, o pior cenário da criação de um PCH (cabeçalho pré-compilado) que contém cada cabeçalho de namespace de projeção do C++/WinRT.
| Versão | Tamanho do PCH (bytes) | Hora (s) |
|---|---|---|
| C++/WinRT de julho, com Visual C++ 16.3 | 3,004,104,632 | 31 |
| versão 2.0.200316.3 do C++/WinRT, com Visual C++ 16.5 | 2,393,515,336 | 24 |
Uma redução de 20% no tamanho e uma redução de 23% no tempo de build.
Suporte aprimorado ao MSBuild
Investimos muito trabalho na melhoria do suporte do MSBuild para uma grande seleção de cenários diferentes.
Armazenamento em cache de fábrica ainda mais rápido
Aprimoramos o inlining do cache de fábrica para embutir melhor os caminhos críticos, o que promove uma execução mais rápida.
Esse aprimoramento não afeta o tamanho do código, conforme descrito abaixo na geração de código EH otimizada, se o aplicativo usar fortemente o tratamento de exceções do C++, você poderá reduzir seu binário usando a opção/d2FH4, que está ativada por padrão em novos projetos criados com Visual Studio 2019 16.3 e posterior.
Boxe mais eficiente
Quando usado em um aplicativo XAML, o winrt::box_value agora é mais eficiente (consulte Empacotamento e desempacotamento). Os aplicativos que fazem muita conversão boxing também terão uma redução no tamanho do código.
Suporte para implementar interfaces COM que implementam iInspectable
Se você precisar implementar uma interface COM (que não seja Windows Runtime) que por acaso implemente IInspectable, agora você pode fazer isso com C++/WinRT. Consulte as interfaces COM que implementam IInspectable.
Melhorias de bloqueio de módulo
O controle sobre o bloqueio de módulo agora permite cenários de hospedagem personalizados e a eliminação total do bloqueio no nível do módulo. Confira Aprimoramentos de bloqueio de módulo.
Suporte para informações de erro que não são do Windows Runtime
Algumas APIs (até mesmo algumas APIs do Windows Runtime) relatam erros sem usar APIs de origem de erros do Windows Runtime. Em casos como esse, o C++/WinRT agora volta a usar informações de erro COM. Consulte o suporte do C++/WinRT para obter informações de erro que não são do WinRT.
Habilitar o suporte ao módulo C++
O suporte ao módulo C++ está de volta, mas apenas em uma forma experimental. O recurso ainda não foi concluído no compilador C++.
Retomada de corrotina mais eficiente
As coroutinas C++/WinRT já têm um bom desempenho, mas continuamos procurando maneiras de melhorar isso. Confira Aumentar a escalabilidade da retomada de corrotina.
Novas funções auxiliares assíncronas when_all e when_any
A função auxiliar do when_all cria um objeto IAsyncAction que é concluído quando todos os aguardáveis fornecidos são concluídos. A função auxiliar do when_any cria um objeto IAsyncAction que é concluído quando qualquer um dos aguardáveis fornecidos são concluídos.
Confira Adicionar o auxiliar assíncrono when_any e Adicionar o auxiliar assíncrono when_all.
Outras otimizações e adições
Além disso, muitas correções de erros, pequenas otimizações e adições foram incluídas, incluindo vários aprimoramentos para simplificar a depuração e otimizar elementos internos e implementações padrão. Siga este link para obter uma lista completa: https://github.com/microsoft/xlang/pulls?q=is%3Apr+is%3Aclosed.
Notícias e alterações, em C++/WinRT 2.0
Para mais informações sobre a Extensão do Visual Studio para C++/WinRT (VSIX), o pacote NuGet Microsoft.Windows.CppWinRT e a cppwinrt.exe ferramenta — incluindo como adquiri-los e instalá-los — consulte o suporte do Visual Studio para C++/WinRT, XAML, a extensão VSIX e o pacote NuGet.
Alterações na VSIX (Extensão de Visual Studio) do C++/WinRT para a versão 2.0
- O visualizador de depuração agora dá suporte ao Visual Studio 2019; além de continuar a dar suporte ao Visual Studio 2017.
- Várias correções de bug foram feitas.
Alterações no pacote NuGet Microsoft.Windows.CppWinRT para a versão 2.0
- A ferramenta
cppwinrt.exeagora está incluída no pacote NuGet Microsoft.Windows.CppWinRT, e a ferramenta gera cabeçalhos de projeção de plataforma para cada projeto, sob demanda. Consequentemente, acppwinrt.exeferramenta não depende mais do SDK de Windows (embora a ferramenta ainda seja fornecida com o SDK por motivos de compatibilidade). -
cppwinrt.exeAgora gera cabeçalhos de projeção em cada pasta intermediária específica da plataforma/configuração ($IntDir) para permitir compilações paralelas. - O suporte de build do C++/WinRT (props/targets) agora está totalmente documentado, caso você deseje personalizar manualmente seus arquivos de projeto. Consulte o README do pacote NuGet Microsoft.Windows.CppWinRT.
- Várias correções de bug foram feitas.
Alterações no C++/WinRT para a versão 2.0
Código aberto
A cppwinrt.exe ferramenta usa um arquivo de metadados Windows Runtime (.winmd) e gera a partir dele uma biblioteca C++ padrão baseada em arquivo de cabeçalho que projeta as APIs descritas nos metadados. Dessa forma, você pode consumir essas APIs a partir do seu código C++/WinRT.
Essa ferramenta agora é um projeto totalmente código aberto, disponível em GitHub. Visite Microsoft/cppwinrt.
bibliotecas xlang
Uma biblioteca totalmente portátil, apenas de cabeçalho (para analisar o formato de metadados ECMA-335 usado pelo Windows Runtime), serve de base para todas as ferramentas do Windows Runtime e do xlang de agora em diante. Vale destacar que também reescrevemos a ferramenta cppwinrt.exe do zero usando as bibliotecas xlang. Isso fornece consultas de metadados muito mais precisas, resolvendo alguns problemas de longa data com a projeção de linguagem C++/WinRT.
Menos dependências
Devido ao leitor de metadados xlang, a cppwinrt.exe própria ferramenta tem menos dependências. Isso o torna muito mais flexível, além de ser utilizável em mais cenários, especialmente em ambientes de build restritos. Notavelmente, não depende mais de RoMetadata.dll.
Essas são as dependências para cppwinrt.exe 2.0.
- ADVAPI32.dll
- KERNEL32.dll
- SHLWAPI.dll
- XmlLite.dll
Todas essas DLLs estão disponíveis não apenas em Windows 10, mas até Windows 7 e até mesmo Windows Vista. Se você quiser, seu servidor de build antigo que roda Windows 7 agora pode executar cppwinrt.exe para gerar cabeçalhos C++ para o seu projeto. Com um pouco de trabalho, você pode até mesmo executar C++/WinRT em Windows 7, se isso lhe interessar.
Contraste a lista acima com essas dependências, que cppwinrt.exe 1.0 tem.
- ADVAPI32.dll
- SHELL32.dll
- api-ms-win-core-file-l1-1-0.dll
- XmlLite.dll
- api-ms-win-core-libraryloader-l1-2-0.dll
- api-ms-win-core-processenvironment-l1-1-0.dll
- RoMetadata.dll
- SHLWAPI.dll
- KERNEL32.dll
- api-ms-win-core-rtlsupport-l1-1-0.dll
- api-ms-win-core-heap-l1-1-0.dll
- api-ms-win-core-timezone-l1-1-0.dll
- api-ms-win-core-console-l1-1-0.dll
- api-ms-win-core-localization-l1-2-0.dll
- OLEAUT32.dll
- api-ms-win-core-winrt-error-l1-1-0.dll
- api-ms-win-core-winrt-error-l1-1-1.dll
- api-ms-win-core-winrt-l1-1-0.dll
- api-ms-win-core-winrt-string-l1-1-0.dll
- api-ms-win-core-synch-l1-1-0.dll
- api-ms-win-core-threadpool-l1-2-0.dll
- api-ms-win-core-com-l1-1-0.dll
- api-ms-win-core-com-l1-1-1.dll
- api-ms-win-core-synch-l1-2-0.dll
O atributo Windows Runtime noexcept
O Windows Runtime tem um novo [noexcept] atributo, que você pode usar para decorar seus métodos e propriedades em MIDL 3.0. A presença do atributo indica às ferramentas de suporte que sua implementação não gera uma exceção (nem retorna um HRESULT com falha). Isso permite que as projeções de linguagem otimizem a geração de código, evitando a sobrecarga de tratamento de exceções necessária para dar suporte a chamadas da ABI (interface binária do aplicativo) que podem potencialmente falhar.
O C++/WinRT tira proveito disso ao produzir implementações em C++ noexcept tanto do código de consumo quanto do código de autoria. Se você tiver métodos de API ou propriedades sem falhas e estiver preocupado com o tamanho do código, poderá investigar esse atributo.
Geração de código otimizada
O C++/WinRT agora gera um código-fonte C++ ainda mais eficiente (nos bastidores) para que o compilador C++ possa produzir o menor e mais eficiente código binário possível. Muitas das melhorias são direcionadas a reduzir o custo de manipulação de exceção, evitando informações de desenrolamento desnecessárias. Binários que usam grandes quantidades de código C++/WinRT verão cerca de 4% redução no tamanho do código. O código também é mais eficiente (é executado mais rapidamente) devido à contagem de instruções reduzida.
Essas melhorias também dependem de um novo recurso de interoperabilidade disponível para você. Todos os tipos C++/WinRT que são proprietários de recursos agora incluem um construtor para assumir a propriedade diretamente, evitando a abordagem anterior de duas etapas.
ABI::Windows::Foundation::IStringable* raw = ...
IStringable projected(raw, take_ownership_from_abi);
printf("%ls\n", projected.ToString().c_str());
Geração de código EH (tratamento de exceções) otimizada
Essa alteração complementa o trabalho que foi feito pela equipe de otimizador do Microsoft C++ para reduzir o custo de tratamento de exceções. Se você usar intensamente ABIs (interfaces binárias de aplicativos) (como COM) no seu código, notará muito código seguindo esse padrão.
int32_t Function() noexcept
{
try
{
// code here constitutes unique value.
}
catch (...)
{
// code here is always duplicated.
}
}
O próprio C++/WinRT gera esse padrão para cada API implementada. Com milhares de funções de API, qualquer otimização aqui pode ser significativa. No passado, o otimizador não detectava que esses blocos de captura eram todos idênticos, então ele estava duplicando muito código em torno de cada ABI (o que, por sua vez, contribuiu para a crença de que o uso de exceções no código do sistema produz binários grandes). No entanto, do Visual Studio de 2019 em diante, o compilador C++ dobra todos esses catch funclets e armazena apenas os que são exclusivos. O resultado é uma redução adicional e geral de 18% no tamanho do código para binários que dependem fortemente desse padrão. Não só o código EH agora é mais eficiente do que usar códigos de retorno, mas também a preocupação com binários maiores agora é coisa do passado.
Melhorias incrementais na compilação
A cppwinrt.exe ferramenta agora compara a saída de um arquivo de cabeçalho/origem gerado com o conteúdo de qualquer arquivo existente no disco e grava o arquivo somente se o arquivo tiver sido alterado de fato. Isso economiza tempo considerável com a E/S do disco e garante que os arquivos não sejam considerados "sujos" pelo compilador C++. O resultado é que a recompilação é evitada ou reduzida, em muitos casos.
Interfaces genéricas agora são todas geradas
Devido ao leitor de metadados xlang, o C++/WinRT agora gera todas as interfaces parametrizadas ou genéricas de metadados. Interfaces como Windows::Foundation::Collections::IVector<T> agora são geradas a partir de metadados em vez de escritas à mão.winrt/base.h O resultado é que o tamanho do winrt/base.h foi cortado pela metade e que as otimizações são geradas diretamente no código (o que foi complicado de fazer com a abordagem rolada à mão).
Important
Interfaces como o exemplo fornecido agora aparecem em seus respectivos cabeçalhos de namespace, em vez de em winrt/base.h. Portanto, se você ainda não fez isso, precisará incluir o cabeçalho de namespace apropriado para usar a interface.
Otimizações de componente
Esta atualização adiciona suporte para várias otimizações de aceitação adicionais para C++/WinRT, descritas nas seções abaixo. Como essas otimizações são alterações significativas (e você talvez precise fazer pequenas alterações para dar suporte a elas), será preciso ativá-las explicitamente. Em Visual Studio, defina a propriedade de projeto Common Properties>C++/WinRT>Otimizada para Sim. Isso tem o efeito de adicionar <CppWinRTOptimized>true</CppWinRTOptimized> ao arquivo de projeto. E tem o mesmo efeito que adicionar a opção -opt[imize] ao invocar cppwinrt.exe pela linha de comando.
Um novo projeto (a partir de um modelo de projeto) usará -opt por padrão.
Construção uniforme e acesso direto à implementação
Essas duas otimizações permitem que seu componente acesse diretamente seus próprios tipos de implementação, mesmo quando ele está usando apenas os tipos projetados. Não é necessário usar make, make_self nem get_self se você simplesmente quiser usar a superfície da API pública. Suas chamadas serão compiladas para chamadas diretas na implementação e elas poderão, inclusive, ser totalmente embutidas.
Para obter mais informações e exemplos de código, consulte Aceitar a construção uniforme e o acesso direto à implementação.
Fábricas de tipo apagado
Essa otimização evita as dependências module.g.cpp de #include para que elas não precisem ser recompiladas sempre que qualquer classe de implementação única for alterada. O resultado é um desempenho de build aprimorado.
Mais inteligente e eficiente module.g.cpp para projetos grandes com várias libs
O arquivo module.g.cpp agora também contém dois auxiliares combináveis adicionais chamados winrt_can_unload_now e winrt_get_activation_factory. Eles foram projetados para projetos maiores em que uma DLL é composta por uma série de libs, cada uma com suas próprias classes de runtime. Nessa situação, você precisa interligar manualmente as funções da DLL DllGetActivationFactory e DllCanUnloadNow. Esses auxiliares facilitam muito para você fazer isso, evitando erros de origem espúria. A opção -lib da ferramenta cppwinrt.exe também pode ser usada para dar a cada biblioteca individual seu próprio preâmbulo (em vez de winrt_xxx), para que as funções de cada biblioteca possam ser nomeadas individualmente e, assim, combinadas sem ambiguidade.
Suporte a rotina combinada
O suporte a rotina combinada está incluído automaticamente. Anteriormente, o suporte residia em vários lugares, o que achamos muito limitador. E então, temporariamente, na v2.0, foi necessário um arquivo de cabeçalho winrt/coroutine.h, mas isso não é mais necessário. Como as interfaces assíncronas Windows Runtime agora são geradas, em vez de escritas à mão, elas agora residem em winrt/Windows.Foundation.h. Além de ter uma manutenção e um suporte mais fáceis, isso significa que os auxiliares de rotina combinada, como resume_foreground, não precisam ser incluídos no final de um cabeçalho de namespace específico. Em vez disso, eles podem incluir mais naturalmente suas dependências. Além disso, isso permite que resume_foreground dê suporte não apenas à retomada em um determinado Windows::UI::Core::CoreDispatcher, mas agora também à retomada em um determinado Windows::System::DispatcherQueue. Anteriormente, apenas um podia ter suporte; mas não ambos, pois a definição só pode residir em um namespace.
Aqui está um exemplo do suporte ao DispatcherQueue .
...
#include <winrt/Windows.System.h>
using namespace Windows::System;
...
fire_and_forget Async(DispatcherQueueController controller)
{
bool queued = co_await resume_foreground(controller.DispatcherQueue());
assert(queued);
// This is just to simulate queue failure...
co_await controller.ShutdownQueueAsync();
queued = co_await resume_foreground(controller.DispatcherQueue());
assert(!queued);
}
Os auxiliares de rotina combinada agora também são decorados com [[nodiscard]], melhorando sua facilidade de uso. Se você esquecer-se, ou não perceber que precisa, de realizar co_await com relação a eles para que funcionem devido a [[nodiscard]], esses erros agora produzirão um aviso do compilador.
Ajuda com o diagnóstico de alocações diretas (pilha)
Como os nomes das classes projetadas e de implementação são (por padrão) iguais e se diferenciam apenas pelo namespace, é possível confundir uma com a outra e acabar criando acidentalmente uma implementação na pilha, em vez de usar a família de funções auxiliares make. Isso pode ser difícil de diagnosticar em alguns casos, pois o objeto pode ter sido destruído enquanto as referências pendentes ainda estão disponibilizadas em versão piloto. Uma asserção agora pega isso para depurar builds. Embora a asserção não detecte a alocação de pilha dentro de uma rotina combinada, ainda é útil para capturar a maioria desses erros.
Para obter mais informações, consulte Diagnosticando alocações diretas.
Auxiliares de captura aprimorados e delegados de variadic
Essa atualização corrige a limitação com os auxiliares de captura, dando suporte também a tipos projetados. Isso aparece agora e então com as APIs de interoperabilidade do Windows Runtime, quando retornam um tipo projetado.
Essa atualização também adiciona suporte para get_strong e get_weak ao criar um delegado variável (não Windows Runtime).
Suporte para destruição adiada e QI segura durante a destruição
Não é incomum no destruidor de um objeto de classe de runtime chamar um método que eleva temporariamente a contagem de referência. Quando a contagem de referência retorna a zero, o objeto é destruído uma segunda vez. Em um aplicativo XAML, você pode precisar executar uma QI (QueryInterface) em um destruidor para chamar uma implementação de limpeza acima ou abaixo na hierarquia. Mas a contagem de referência do objeto já atingiu zero, de modo que essa QI também constitui um salto na contagem.
Essa atualização adiciona suporte para eliminar o salto da contagem de referência, garantindo que, após atingir zero, ele nunca mais possa ser reativado, enquanto ainda permite QI para qualquer temporário necessário durante a destruição. Este procedimento é inevitável em determinados aplicativos/controles XAML e o C++/WinRT agora é resiliente a ele.
Você pode adiar a destruição fornecendo uma função estática final_release no seu tipo de implementação. Esse último ponteiro restante para o objeto, na forma de um std::unique_ptr, é passado para seu final_release. Você pode, em seguida, optar por mover a propriedade desse ponteiro para algum outro contexto. É seguro executar QI com o ponteiro sem acionar uma destruição dupla. Mas a variação líquida na contagem de referência deve ser igual a zero no momento em que você destrói o objeto.
O valor retornado de final_release pode ser void, um objeto de operação assíncrono, como IAsyncAction ou winrt::fire_and_forget.
struct Sample : implements<Sample, IStringable>
{
hstring ToString()
{
return L"Sample";
}
~Sample()
{
// Called when the unique_ptr below is reset.
}
static void final_release(std::unique_ptr<Sample> self) noexcept
{
// Move 'self' as needed to delay destruction.
}
};
No exemplo a seguir, uma vez que MainPage é liberada (para a hora final), final_release é chamada. Essa função passa cinco segundos aguardando (no pool de threads) e, em seguida, retoma o uso do Dispatcher da página (que requer QI/AddRef/Release para funcionar). Em seguida, ela limpa um recurso nesse thread da interface do usuário. E, por fim, limpa unique_ptr, fazendo com que o destruidor de MainPage realmente seja chamado. Mesmo nesse destruidor, DataContext é chamado, o que requer uma QI para IFrameworkElement.
Você não precisa implementar sua final_release como uma corrotina. Mas isso funciona e torna muito simples mover a destruição para um thread diferente, que é o que está acontecendo neste exemplo.
struct MainPage : PageT<MainPage>
{
MainPage()
{
}
~MainPage()
{
DataContext(nullptr);
}
static IAsyncAction final_release(std::unique_ptr<MainPage> self)
{
co_await 5s;
co_await resume_foreground(self->Dispatcher());
co_await self->resource.CloseAsync();
// The object is destructed normally at the end of final_release,
// when the std::unique_ptr<MyClass> destructs. If you want to destruct
// the object earlier than that, then you can set *self* to `nullptr`.
self = nullptr;
}
};
Para obter mais informações, consulte Destruição adiada.
Suporte aprimorado para herança de interface única no estilo COM
Além de ser usado para programação do Windows Runtime, o C++/WinRT também é usado para desenvolver e consumir APIs exclusivas de COM. Essa atualização possibilita implementar um servidor COM em que existe uma hierarquia de interface. Isso não é necessário para o Windows Runtime; mas é necessário para algumas implementações COM.
Manipulação correta de out parâmetros
Pode ser complicado trabalhar com out parâmetros; particularmente Windows Runtime matrizes. Com esta atualização, C++/WinRT é consideravelmente mais robusto e tolerante a erros quando se trata de out parâmetros e arrays, quer esses parâmetros cheguem por meio de uma projeção de linguagem ou de um desenvolvedor COM que esteja usando a ABI bruta e cometendo o erro de não inicializar as variáveis de maneira consistente. Em ambos os casos, o C++/WinRT agora faz a coisa certa quando se trata de passar tipos projetados para a ABI (lembrando-se de liberar quaisquer recursos), e quando se trata de zerar ou limpar parâmetros que chegam pela ABI.
Os eventos agora lidam com tokens inválidos de forma confiável
A implementação de winrt::event agora manipula normalmente o caso em que seu método de remoção é chamado com um valor de token inválido (um valor que não está presente na matriz).
As variáveis locais da corrotina agora são destruídas antes de a corrotina retornar
A maneira tradicional de implementar um tipo de corrotina pode permitir que variáveis locais dentro da corrotina sejam destruídas após ela retornar/ser concluída (em vez de antes da suspensão final). A retomada de qualquer garçom agora é adiada até a suspensão final, a fim de evitar esse problema e acumular outros benefícios.
Notícias e alterações, no SDK Windows versão 10.0.17763.0 (Windows 10, versão 1809)
A tabela a seguir contém notícias e alterações para C++/WinRT no SDK Windows versão 10.0.17763.0 (Windows 10, versão 1809).
| Recurso novo ou alterado | Mais informações |
|---|---|
| Alteração significativa. Para compilar, o C++/WinRT não depende de cabeçalhos do SDK do Windows. | Veja Isolamento de arquivos de cabeçalho do SDK do Windows, abaixo. |
| O formato do sistema de projeto Visual Studio foi alterado. | Veja como redirecionar seu projeto C++/WinRT para uma versão posterior do SDK do Windows, abaixo. |
| Há novas funções e classes base para ajudá-lo a passar um objeto de coleção para uma função Windows Runtime ou implementar suas próprias propriedades de coleção e tipos de coleção. | Consulte Coleções com C++/WinRT. |
| Você pode usar a extensão de marcação {Binding} com suas classes de runtime do C++/WinRT. | Para obter mais informações e exemplos de código, consulte a visão geral da associação de dados. |
| O suporte ao cancelamento de uma rotina combinada permite que você registre um retorno de chamada de cancelamento. | Para obter mais informações e exemplos de código, consulte Cancelando uma operação assíncrona e cancelando retornos de chamada. |
| Ao criar um delegado que aponta para uma função de membro, você pode estabelecer uma referência forte ou fraca ao objeto atual (em vez de um ponteiro this bruto) no ponto em que o manipulador é registrado. | Para obter mais informações e exemplos de código, veja a subseção Se você usar uma função de membro como delegado na seção Acessar com segurança o ponteiro this com um delegado de manipulação de eventos. |
| Foram corrigidos erros descobertos graças à conformidade aprimorada do Visual Studio com o padrão da linguagem C++. A cadeia de ferramentas LLVM e Clang também é melhor aproveitada para validar a conformidade dos padrões do C++/WinRT. | Você não encontrará mais o problema descrito em Por que meu novo projeto não será compilado? Estou usando Visual Studio 2017 (versão 15.8.0 ou posterior) e o SDK versão 17134 |
Outras alterações.
-
Alteração significativa.
winrt::get_abi(winrt::hstring const&) agora retorna
void*em vez deHSTRING. Você pode usarstatic_cast<HSTRING>(get_abi(my_hstring));para obter um HSTRING. Consulte a interoperação com o HSTRING da ABI. -
Alteração significativa.
winrt::put_abi(winrt::hstring&) agora retorna
void**em vez deHSTRING*. Você pode usarreinterpret_cast<HSTRING*>(put_abi(my_hstring));para obter um HSTRING*. Consulte a interoperação com o HSTRING da ABI. -
Alteração significativa. O HRESULT agora é projetado como winrt::hresult. Se você precisar de um HRESULT (para fazer verificação de tipo ou para dar suporte a características de tipo), poderá
static_castfazer um winrt::hresult. Caso contrário, winrt::hresult converte em HRESULT, desde que você incluaunknwn.hantes de incluir quaisquer cabeçalhos C++/WinRT. -
Alteração significativa. O GUID agora é projetado como winrt::guid. Para as APIs que você implementa, você deve usar winrt::guid para parâmetros do tipo GUID. Caso contrário, winrt::guid converterá em GUID, desde que você inclua
unknwn.hantes de incluir quaisquer cabeçalhos C++/WinRT. Consulte Interoperando com a estrutura GUID da ABI. - Alteração significativa. O construtor winrt::handle_type foi protegido, tornando-o explícito (agora é mais difícil escrever código incorreto com ele). Se você precisar atribuir um valor de identificador bruto, chame a função handle_type::attach em vez disso.
-
Alteração significativa. As assinaturas de WINRT_CanUnloadNow e WINRT_GetActivationFactory foram alteradas. Você não pode declarar essas funções de forma alguma. Em vez disso, inclua
winrt/base.h(que é incluído automaticamente se você incluir qualquer arquivo de cabeçalho de namespace do Windows do C++/WinRT) para incluir as declarações destas funções. - Para o struct winrt::clock, from_FILETIME/to_FILETIME são preteridos em favor de from_file_time/to_file_time.
- APIs simplificadas que esperam parâmetros IBuffer. A maioria das APIs prefere coleções ou matrizes. Mas achamos que deveríamos facilitar a chamada de APIs que dependem do IBuffer. Essa atualização fornece acesso direto aos dados por trás de uma implementação do IBuffer . Ele usa a mesma convenção de nomenclatura de dados usada pelos contêineres da Biblioteca Padrão do C++. Essa convenção também evita colisões com nomes de metadados que começam convencionalmente com uma letra maiúscula.
- Melhor geração de código: várias melhorias para reduzir o tamanho do código, melhorar o sublinhado e otimizar o cache de fábrica.
- Remoção da recursão desnecessária. Quando a linha de comando se refere a uma pasta, em vez de a uma específica
.winmd, acppwinrt.exeferramenta não pesquisa mais recursivamente arquivos.winmd. Acppwinrt.exeferramenta também agora lida com duplicatas de forma mais inteligente, tornando-a mais resiliente ao erro do usuário e a arquivos mal formados.winmd. - Ponteiros inteligentes reforçados. Anteriormente, os revogadores de evento falhavam em revogar quando movidos-recebiam um novo valor. Isso ajudou a descobrir um problema em que classes de ponteiro inteligente não estavam manipulando de modo confiável a autoatribuição; como raiz no modelo de struct winrt::com_ptr. winrt::com_ptr foi corrigido e os revogadores de eventos foram corrigidos para lidar corretamente com a semântica de movimentação, de modo que sejam revogados após a atribuição.
Important
Alterações importantes foram feitas no VSIX (Extensão de Visual Studio) do C++/WinRT, tanto na versão 1.0.181002.2 quanto posterior na versão 1.0.190128.4. Para obter detalhes dessas alterações e como elas afetam seus projetos existentes, Visual Studio suporte para c++/WinRT e versões anteriores da extensão VSIX.
Isolamento de arquivos de cabeçalho do SDK do Windows
Essa é possivelmente uma alteração da falha para seu código.
Para que ele seja compilado, O C++/WinRT não depende mais dos arquivos de cabeçalho do SDK do Windows. Os arquivos de cabeçalho na CRT (biblioteca de tempo de execução) C e na STL (Biblioteca de Modelos Padrão) do C++ também não incluem nenhum cabeçalho Windows SDK. E isso melhora a conformidade de padrões, evita dependências inadvertidas e reduz consideravelmente o número de macros que você precisa proteger.
Essa independência significa que o C++/WinRT agora é mais portátil e compatível com padrões e aumenta a possibilidade de ele se tornar um compilador cruzado e uma biblioteca multiplataforma. Isso também significa que os cabeçalhos C++/WinRT não são afetados negativamente por macros.
Se antes você deixava a cargo do C++/WinRT incluir quaisquer cabeçalhos do Windows no seu projeto, agora precisará incluí-los você mesmo. Em qualquer caso, é sempre uma melhor prática incluir explicitamente os cabeçalhos de que você depende e não deixar que outra biblioteca os inclua para você.
Atualmente, as únicas exceções para o isolamento dos arquivos de cabeçalho do SDK do Windows são para intrínsecos e tipos numéricos. Não há problemas conhecidos com essas últimas dependências restantes.
Em seu projeto, você pode habilitar novamente a interoperabilidade com os cabeçalhos do SDK Windows, se necessário. Você pode, por exemplo, querer implementar uma interface COM (com raiz no IUnknown). Para esse exemplo, inclua unknwn.h antes de incluir quaisquer cabeçalhos C++/WinRT. Isso faz com que a biblioteca base C++/WinRT habilite vários ganchos para dar suporte a interfaces COM clássicas. Para obter um exemplo de código, consulte Criar componentes COM com C++/WinRT. Da mesma forma, inclua explicitamente quaisquer outros arquivos de cabeçalho do SDK do Windows que declarem tipos e/ou funções que você deseja chamar.
Como redirecionar seu projeto C++/WinRT para uma versão posterior do SDK do Windows
O método para seu projeto que provavelmente resultará no menor número de problemas de compilador e vinculador também é o mais trabalhoso. Esse método envolve a criação de um novo projeto (direcionando a versão do SDK Windows de sua escolha) e, em seguida, copiar arquivos para o novo projeto do seu antigo. Haverá seções nos seus arquivos antigos .vcxproj e .vcxproj.filters que você pode simplesmente copiar para evitar ter que adicionar arquivos no Visual Studio.
No entanto, há duas outras maneiras de redirecionar seu projeto em Visual Studio.
- Vá para a propriedade de projeto General>Windows Versão do SDK e selecione Todas as Configurações e Todas as Plataformas. Defina Versão do SDK do Windows para a versão que você deseja usar como destino.
- Em Gerenciador de Soluções, clique com o botão direito do mouse no nó do projeto, clique em Projetos do Retarget, escolha as versões que você deseja direcionar e clique em OK.
Se você encontrar erros de compilador ou vinculador depois de usar um desses dois métodos, poderá tentar limpar a solução (Criar>solução limpa e/ou excluir manualmente todas as pastas e arquivos temporários) antes de tentar compilar novamente.
Se o compilador C++ produzir "erro C2039: 'IUnknown': não é um membro do ''namespace global''", adicione #include <unknwn.h> à parte superior do arquivo (antes de pch.h incluir quaisquer cabeçalhos C++/WinRT).
Talvez você também precise adicionar #include <hstring.h> depois disso.
Se o vinculador do C++ produzir "erro LNK2019: símbolo externo não resolvido _WINRT_CanUnloadNow@0 referenciado na função _VSDesignerCanUnloadNow@0", você poderá resolver isso adicionando #define _VSDESIGNER_DONT_LOAD_AS_DLL ao seu pch.h arquivo.
Windows developer