Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
À medida que as versões subsequentes de C++/WinRT são lançadas, este tópico descreve o que há de novo e o que mudou.
Compilação das melhorias e adições recentes até março de 2020
Até 23% tempos de construção mais curtos
As equipas de compiladores de C++/WinRT e C++ colaboraram para fazer tudo o possível para encurtar os tempos de compilação. Analisámos análises de compiladores para perceber como o interior do C++/WinRT pode ser reestruturado para ajudar o compilador C++ a eliminar a sobrecarga de tempo de compilação, bem como como o próprio compilador C++ pode ser melhorado para gerir a biblioteca C++/WinRT. C++/WinRT foi otimizado para o compilador; e o compilador foi otimizado para C++/WinRT.
Vejamos, por exemplo, o pior cenário de construir um cabeçalho pré-compilado (PCH) que contenha todos os cabeçalhos de namespace de projeção C++/WinRT.
| Versão | Tamanho do PCH (bytes) | Tempo (s) |
|---|---|---|
| C++/WinRT a partir de julho, com Visual C++ 16.3 | 3,004,104,632 | 31 |
| versão 2.0.200316.3 de 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 construção.
Suporte melhorado ao MSBuild
Investimos muito trabalho em melhorar o suporte do MSBuild para uma grande variedade de cenários diferentes.
Cache de fábrica ainda mais rápido
Melhorámos a expansão em linha da cache de fábrica para expandir melhor em linha os caminhos críticos, o que resulta numa execução mais rápida.
Essa melhoria não afeta o tamanho do código — como descrito abaixo em Optimized EH code-gen, se a sua aplicação usar fortemente o tratamento de exceções em C++, pode encolher o binário usando a /d2FH4 opção, que está ativada por defeito em novos projetos criados com Visual Studio 2019 16.3 e posteriores.
Boxe mais eficiente
Quando utilizado numa aplicação XAML, winrt::box_value é agora mais eficiente (ver Boxing and unboxing). Aplicações que fazem muito boxing também notarão uma redução no tamanho do código.
Suporte para implementar interfaces COM que implementam IInspectable
Se precisares de implementar uma interface COM (nãoWindows-Runtime) que por acaso implementa o IInspectable, então agora podes fazê-lo com C++/WinRT. Veja interfaces COM que implementam IInspectable.
Melhorias no bloqueio de módulos
O controlo sobre o bloqueio do módulo permite agora tanto cenários de alojamento personalizados como a eliminação total do bloqueio ao nível do módulo. Ver melhorias no bloqueio de módulos.
Suporte para informação de erro não pertencente ao Windows Runtime
Algumas APIs (até algumas APIs do Windows Runtime) reportam erros sem usar APIs de origem de erros do Windows Runtime. Nesses casos, o C++/WinRT passa agora a recorrer a informações de erro do COM. Consulte o suporte a C++/WinRT para informações de erro não relacionadas com o WinRT.
Ativar o suporte a módulos C++
O suporte para módulos C++ está de volta, mas apenas numa forma experimental. A funcionalidade ainda não está completa no compilador C++.
Retomada de corrotinas mais eficiente
As corrotinas C++/WinRT já apresentam um bom desempenho, mas continuamos a procurar formas de melhorar esse desempenho. Veja Melhorar a escalabilidade da retomada de corrotinas.
Novos when_all e when_any ajudantes assíncronos
A função auxiliar when_all cria um objeto IAsyncAction que se completa quando todos os awaitables fornecidos estão concluídos. O ajudante when_any cria uma IAsyncAction que se completa quando qualquer um dos awaitables fornecidos foi concluído.
Consulte Adicionar o auxiliar assíncrono when_any e Adicionar o auxiliar assíncrono when_all.
Outras otimizações e adições
Além disso, foram introduzidas muitas correções de erros e pequenas otimizações e adições, incluindo várias melhorias para simplificar a depuração e otimizar os componentes internos e as implementações predefinidas. Siga este link para uma lista exaustiva: https://github.com/microsoft/xlang/pulls?q=is%3Apr+is%3Aclosed.
Notícias e mudanças em C++/WinRT 2.0
Para mais informações sobre a Extensão do Visual Studio (VSIX) para C++/WinRT, o pacote NuGet Microsoft.Windows.CppWinRT e a ferramenta cppwinrt.exe — incluindo como os adquirir e instalar — consulte o suporte do Visual Studio para C++/WinRT, XAML, a extensão VSIX e o pacote NuGet.
Alterações à Extensão Visual Studio (VSIX) C++/WinRT para a versão 2.0
- O visualizador de depuração suporta agora o Visual Studio 2019; além de continuar a suportar o Visual Studio 2017.
- Foram feitas várias correções de bugs.
Alterações ao pacote NuGet Microsoft.Windows.CppWinRT na versão 2.0
- A ferramenta
cppwinrt.exeestá agora incluída no pacote NuGet Microsoft.Windows.CppWinRT e gera ficheiros de cabeçalho de projeção de plataforma para cada projeto, a pedido. Consequentemente, acppwinrt.exeferramenta já não depende do SDK do Windows (embora, por razões de compatibilidade, ainda venha com o SDK). -
cppwinrt.exeAgora gera cabeçalhos de projeção sob cada pasta intermédia ($IntDir) específica de plataforma/configuração para permitir compilações paralelas. - O suporte para compilações em C++/WinRT (props/targets) está agora totalmente documentado, caso queira personalizar manualmente os ficheiros do seu projeto. Consulte o ficheiro readme do pacote NuGet Microsoft.Windows.CppWinRT.
- Foram feitas várias correções de bugs.
Alterações para C++/WinRT para a versão 2.0
Código aberto
A cppwinrt.exe ferramenta pega num ficheiro de metadados do Windows Runtime (.winmd) e gera a partir dele uma biblioteca padrão C++ baseada em ficheiros de cabeçalho que projeta as APIs descritas nos metadados. Assim, podes consumir essas APIs do teu código C++/WinRT.
Esta ferramenta é agora um projeto totalmente open source, disponível no GitHub. Visite Microsoft/cppwinrt.
Bibliotecas Xlang
Uma biblioteca totalmente portátil apenas com cabeçalhos (para analisar o formato de metadados ECMA-335 usado pelo Windows Runtime) constitui a base de todas as ferramentas do Windows Runtime e xlang daqui para a frente. Notavelmente, também reescrevemos a cppwinrt.exe ferramenta do zero usando as bibliotecas xlang. Isto fornece consultas de metadados muito mais precisas, resolvendo alguns problemas antigos com a projeção da linguagem C++/WinRT.
Menos dependências
Devido ao leitor de metadados xlang, a cppwinrt.exe própria ferramenta tem menos dependências. Isto torna-o muito mais flexível, além de ser utilizável em mais cenários — especialmente em ambientes de construção restritos. Notavelmente, já não depende de RoMetadata.dll.
Estas são as dependências da cppwinrt.exe versão 2.0.
- ADVAPI32.dll
- KERNEL32.dll
- SHLWAPI.dll
- XmlLite.dll
Todas essas DLLs estão disponíveis não só no Windows 10, mas até ao Windows 7 e até ao Windows Vista. Se quiseres, o teu antigo servidor de compilação a executar o Windows 7 pode agora executar cppwinrt.exe para gerar os cabeçalhos C++ para o teu projeto. Com algum esforço, podes até correr C++/WinRT no Windows 7, se isso te interessar.
Compare a lista acima com estas dependências, que cppwinrt.exe a versão 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 uma nova [noexcept] característica, que pode usar para decorar os seus métodos e propriedades no MIDL 3.0. A presença do atributo indica às ferramentas de suporte que a sua implementação não lança uma exceção (nem retorna um HRESULT falhado). Isto permite que as projeções de linguagem otimizem a geração de código, evitando a sobrecarga de gestão de exceções necessária para suportar chamadas de interface binária (ABI) de aplicação que podem falhar.
O C++/WinRT aproveita isto ao produzir implementações em C++ noexcept tanto do código consumidor como do código de autoria. Se tiver métodos ou propriedades da API que não falham e estiver preocupado com o tamanho do código, pode então considerar este atributo.
Geração de código otimizada
O C++/WinRT gera agora 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 visam reduzir o custo do tratamento de exceções, evitando informações desnecessárias sobre o desmantelamento. Binários que usam grandes quantidades de código C++/WinRT verão uma redução de cerca de 4% no tamanho do código. O código também é mais eficiente (corre mais rápido) devido à redução do número de instruções.
Estas melhorias dependem de uma nova funcionalidade de interoperabilidade que também está disponível para si. Todos os tipos de C++/WinRT que são proprietários de recursos incluem agora um construtor para assumir a propriedade diretamente, evitando a abordagem anterior de dois passos.
ABI::Windows::Foundation::IStringable* raw = ...
IStringable projected(raw, take_ownership_from_abi);
printf("%ls\n", projected.ToString().c_str());
Geração de código otimizada para o tratamento de exceções (EH)
Esta alteração complementa o trabalho realizado pela equipa de otimizadores C++ da Microsoft para reduzir o custo de gestão de exceções. Se usares fortemente interfaces binárias de aplicação (ABIs) (como COM) no teu código, vais observar muito código a seguir este padrão.
int32_t Function() noexcept
{
try
{
// code here constitutes unique value.
}
catch (...)
{
// code here is always duplicated.
}
}
O próprio C++/WinRT gera este padrão para cada API implementada. Com milhares de funções API, qualquer otimização aqui pode ser significativa. No passado, o otimizador não detetava que esses blocos de captura eram todos idênticos, por isso duplicava muito código em cada ABI (o que, por sua vez, contribuiu para a crença de que usar exceções no código do sistema produz binários grandes). No entanto, a partir do Visual Studio 2019, o compilador de C++ agrupa todos esses funclets catch e armazena apenas os que são únicos. O resultado é uma redução adicional e global de 18% no tamanho do código para binários que dependem fortemente deste padrão. Não só o código EH é agora mais eficiente do que usar códigos de retorno, como também a preocupação com binários maiores é coisa do passado.
Melhorias incrementais na construção
A cppwinrt.exe ferramenta agora compara a saída de um cabeçalho/ficheiro fonte gerado com o conteúdo de qualquer ficheiro existente no disco, e só escreve o ficheiro se este tiver realmente mudado. Isto poupa considerável tempo com I/O de disco e garante que os ficheiros não são considerados "sujos" pelo compilador C++. O resultado é que a recompilação é evitada, ou reduzida, em muitos casos.
As interfaces genéricas são agora todas geradas
Devido ao leitor de metadados xlang, o C++/WinRT gera agora todas as interfaces parametrizadas, ou genéricas, a partir dos metadados. Interfaces como Windows::Foundation::Collections::IVector<T> passam agora a ser geradas a partir de metadados, em vez de serem escritas manualmente em winrt/base.h. O resultado é que o tamanho de winrt/base.h foi reduzido para metade, e que as otimizações são geradas diretamente no código (o que foi complicado de fazer com a abordagem manual).
Important
Interfaces como o exemplo dado aparecem agora nos respetivos cabeçalhos de namespace, em vez de em winrt/base.h. Portanto, se ainda não o fizeste, terás de incluir o cabeçalho de namespace apropriado para poderes usar a interface.
Otimizações de componentes
Esta atualização inclui suporte para diversas otimizações opcionais adicionais para C++/WinRT, descritas nas secções abaixo. Como estas otimizações são alterações disruptivas (que pode ser necessário fazer pequenas alterações para suportar), terá de as ativar explicitamente. No Visual Studio, defina a propriedade do projeto Common Properties>C++/WinRT>Optimized para Yes. Isso tem o efeito de adicionar <CppWinRTOptimized>true</CppWinRTOptimized> ao teu ficheiro de projeto. E tem o mesmo efeito que adicionar o -opt[imize] switch ao invocar cppwinrt.exe a partir da linha de comandos.
Um novo projeto (a partir de um modelo de projeto) usará -opt por predefinição.
Construção uniforme e acesso direto à implementação
Estas duas otimizações permitem que o seu componente tenha acesso direto aos seus próprios tipos de implementação, mesmo quando está apenas a usar os tipos projetados. Não é necessário usar make, make_self nem get_self se simplesmente quiser usar a superfície pública da API. As tuas chamadas serão compiladas em chamadas diretas na implementação, e estas podem até ser totalmente integradas.
Para mais informações e exemplos de código, veja Optar para construção uniforme e acesso direto à implementação.
Fábricas apagadas por tipos
Esta otimização evita as dependências #include em module.g.cpp para que não precise de ser recompilada sempre que qualquer classe de implementação muda. O resultado é uma melhoria no desempenho da construção.
Mais inteligente e eficiente module.g.cpp para grandes projetos com várias bibliotecas
O module.g.cpp ficheiro contém agora também dois auxiliares componíveis adicionais, chamados winrt_can_unload_now e winrt_get_activation_factory. Estes foram concebidos para projetos maiores onde uma DLL é composta por várias libs, cada uma com as suas próprias classes de runtime. Nessa situação, tens de unir manualmente as DLLs DllGetActivationFactory e DllCanUnloadNow. Estes auxiliares facilitam muito isso, evitando erros espúrios de originação. O sinalizador -lib da ferramenta cppwinrt.exe também pode ser usado para atribuir a cada biblioteca o seu próprio preâmbulo (em vez de usar winrt_xxx), para que as funções de cada biblioteca possam ser nomeadas individualmente e, assim, combinadas sem ambiguidade.
Suporte de corrotinas
O suporte às corrotinas é incluído automaticamente. Anteriormente, o apoio estava em vários locais, o que considerávamos demasiado limitativo. E depois, temporariamente, para a v2.0, era necessário um winrt/coroutine.h ficheiro de cabeçalho, mas já não é necessário. Como as interfaces assíncronas do Windows Runtime são agora geradas, em vez de manuscritas, residem agora em winrt/Windows.Foundation.h. Para além de ser mais fácil de manter e de dar suporte, isto significa que funções auxiliares de corrotina, como resume_foreground, já não têm de ser acrescentadas no fim do ficheiro de cabeçalho de um espaço de nomes específico. Em vez disso, podem incluir de forma mais natural as suas dependências. Isto permite ainda que resume_foreground suporte não só retomar a execução num determinado Windows::UI::Core::CoreDispatcher, como também passar a suportar retomar a execução numa determinada Windows::System::DispatcherQueue. Anteriormente, apenas um podia ser suportado; mas não ambos, pois a definição só podia residir num espaço de nomes.
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);
}
As corutinas auxiliares são agora também decoradas com [[nodiscard]], melhorando assim a sua usabilidade. Se se esquecer (ou não se aperceber de que tem de co_await para que funcionem), então, devido a [[nodiscard]], esses erros produzem agora um aviso do compilador.
Ajuda no diagnóstico de alocações diretas (stack)
Como os nomes das classes projetadas e de implementação são (por defeito) os mesmos e só diferem pelo espaço de nomes, é possível confundir uma com a outra e instanciar acidentalmente uma implementação na pilha, em vez de usar a família de auxiliares make. Isto pode ser difícil de diagnosticar em alguns casos, porque o objeto pode ser destruído enquanto ainda existirem referências ativas. Uma asserção deteta agora isto nas compilações de depuração. Embora a afirmação não detete a alocação de pilha dentro de uma corrotina, é ainda assim útil para detetar a maioria desses erros.
Para mais informações, consulte Diagnóstico de alocações diretas.
Ajudantes de captura melhorados e delegados variádicos
Esta atualização corrige a limitação dos auxiliares de captura, passando também a suportar tipos projetados. Isto surge ocasionalmente com as APIs de interoperabilidade do Windows Runtime, quando estas devolvem um tipo projetado.
Esta atualização também adiciona suporte para get_strong e get_weak ao criar um delegado variádico (que não seja do Windows Runtime).
Apoio à destruição adiada e QI seguro durante a destruição
Não é incomum, no destruidor de um objeto de classe em tempo de execução, chamar um método que temporariamente aumenta a contagem de referências. Quando a contagem de referência regressa a zero, o objeto destrói-se uma segunda vez. Numa aplicação XAML, pode ser necessário realizar uma Interface de Consulta (QI) num destruidor, para chamar alguma implementação de limpeza para cima ou para baixo na hierarquia. Mas a contagem de referências do objeto já atingiu zero, pelo que esse QI também constitui uma oscilação na contagem de referências.
Esta atualização adiciona suporte para impedir que a contagem de referências volte a aumentar, garantindo que, assim que atinge zero, nunca possa ser reativada; permitindo ainda efetuar QI para qualquer objeto temporário de que necessite durante a destruição. Este procedimento é inevitável em certas aplicações/controlos XAML, e o C++/WinRT é agora resistente a ele.
Pode adiar a destruição ao fornecer uma função estática final_release no seu tipo de implementação. O último ponteiro restante para o objeto, na forma de std::unique_ptr, é passado ao final_release. Pode então optar por transferir a propriedade desse ponteiro para outro contexto. É seguro para poderes fazer QI no ponteiro sem desencadear uma dupla destruição. Mas a alteração líquida na contagem de referência deve ser zero no momento em que destrói o objeto.
O valor de retorno 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 abaixo, uma vez que a Página Principal é lançada (pela última vez), final_release é chamada. Essa função passa cinco segundos à espera (no pool de threads) e depois retoma utilizando o Dispatcher da página (que requer QI/AddRef/Release para funcionar). Depois, limpa um recurso nesse tópico da interface. E, por fim, limpa o unique_ptr, o que faz com que o destruidor de MainPage seja efetivamente chamado. Mesmo nesse destruidor, DataContext é invocado, o que requer um QI para IFrameworkElement.
Não tens de implementar a tua final_release como uma corrotina. Mas isso funciona e torna muito simples transferir a destruição para outra thread, que é o que está a acontecer 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 mais informações, veja Destruição diferida.
Suporte melhorado para herança de interface única ao estilo COM
Para além da programação Windows Runtime, o C++/WinRT é também utilizado para criar e consumir APIs apenas COM. Esta atualização permite implementar um servidor COM onde existe uma hierarquia de interface. Isto não é obrigatório para o Windows Runtime; mas é obrigatório para algumas implementações COM.
Tratamento correto dos out parâmetros
Pode ser complicado trabalhar com out parâmetros; particularmente com arrays do Windows Runtime. Com esta atualização, o C++/WinRT torna-se consideravelmente mais robusto e resiliente a erros no que diz respeito a parâmetros e arrays out; quer esses parâmetros cheguem através de uma projeção de linguagem, quer de um programador COM que utiliza a ABI de baixo nível e que, por lapso, não inicializa as variáveis de forma consistente. Em qualquer dos casos, o C++/WinRT faz agora o que deve ao passar os tipos projetados para a ABI (garantindo a libertação de quaisquer recursos) e ao repor a zero ou limpar os parâmetros recebidos através da ABI.
Os eventos agora tratam tokens inválidos de forma fiável
A implementação winrt::event gere agora de forma elegante o caso em que o seu método remove é chamado com um valor de token inválido (um valor que não está presente no array).
As variáveis locais da corrotina são agora destruídas antes de a corrotina regressar
A forma tradicional de implementar um tipo de corrotina pode permitir que variáveis locais dentro da corrotina sejam destruídas após o regresso/conclusão da corrotina (em vez de antes da suspensão final). A retomada de qualquer empregado está agora adiada até à suspensão final, para evitar este problema e acumular outros benefícios.
Notícias e alterações no Windows SDK versão 10.0.17763.0 (Windows 10, versão 1809)
A tabela abaixo contém notícias e alterações para C++/WinRT no SDK do Windows versão 10.0.17763.0 (Windows 10, versão 1809).
| Funcionalidade nova ou alterada | Mais informações |
|---|---|
| A quebrar o troco. Para compilar, o C++/WinRT não depende dos cabeçalhos do SDK do Windows. | Veja Isolamento dos ficheiros de cabeçalho do SDK do Windows, abaixo. |
| O formato do sistema de projeto Visual Studio mudou. | Veja abaixo Como redirecionar o seu projeto C++/WinRT para uma versão mais recente do Windows SDK. |
| Existem novas funções e classes base para te ajudar a passar um objeto de coleção para uma função de Windows Runtime, ou para implementar as tuas próprias propriedades e tipos de coleção. | Consulte Coleções com C++/WinRT. |
| Pode usar a extensão de marcação {Binding} com as suas classes de runtime C++/WinRT. | Para mais informações e exemplos de código, consulte Visão Geral da Ligação de Dados. |
| O suporte para cancelar uma corrotina permite registar um callback de cancelamento. | Para mais informações e exemplos de código, veja Cancelar uma operação assíncrona e callbacks de cancelamento. |
| Ao criar um delegado que aponta para uma função-membro, é possível estabelecer uma referência forte ou fraca ao objeto atual (em vez de um simples apontador this) no momento em que o processador é registado. | Para mais informações e exemplos de código, consulte a subsecção Se utilizar uma função membro como delegado na secção Aceder em segurança ao ponteiro this com um delegado para processamento de eventos. |
| Foram corrigidos bugs que foram descobertos pela melhoria da conformidade do Visual Studio com o padrão C++. A cadeia de ferramentas LLVM e Clang também é melhor aproveitada para validar a conformidade com os padrões C++/WinRT. | Já não vai encontrar o problema descrito em Porque é que o meu novo projeto não compila? Estou a usar o Visual Studio 2017 (versão 15.8.0 ou posterior) e o SDK versão 17134 |
Outras alterações.
-
Alteração interruptiva.
winrt::get_abi(winrt::hstring const&) agora retorna
void*em vez deHSTRING. Podes usarstatic_cast<HSTRING>(get_abi(my_hstring));para conseguir um HSTRING. Consulte Interoperar com o HSTRING da ABI. -
A quebrar o troco.
winrt::put_abi(winrt::hstring&) agora devolve
void**em vez deHSTRING*. Podes usarreinterpret_cast<HSTRING*>(put_abi(my_hstring));para obter um HSTRING*. Veja Interoperabilidade com a HSTRING da ABI. -
A quebrar o troco. O HRESULT é agora projetado como winrt::hresult. Se precisares de um HRESULT (para fazer verificação de tipos, ou para apoiar traços de tipo), então podes
static_castusar um winrt::hresult. Caso contrário, winrt::hresult é convertido em HRESULT, desde que incluaunknwn.hantes de quaisquer cabeçalhos C++/WinRT. -
A quebrar o troco. O GUID é agora projetado como winrt::guid. Para as APIs que implementa, deve usar winrt::guid para os parâmetros do tipo GUID. Caso contrário, winrt::guid é convertido em GUID, desde que inclua
unknwn.hantes de incluir quaisquer cabeçalhos C++/WinRT. Ver Interoperar com a estrutura GUID da ABI. - A quebrar o troco. O construtor winrt::handle_type foi reforçado tornando-o explícito (agora é mais difícil escrever código incorreto com ele). Se precisares de atribuir um valor bruto de handle, chama a função handle_type::attach em vez disso.
-
A quebrar o troco. As assinaturas de WINRT_CanUnloadNow e WINRT_GetActivationFactory mudaram. Não deve declarar estas funções de forma alguma. Em vez disso, inclua
winrt/base.h(que é incluído automaticamente se incluir qualquer ficheiro de cabeçalho do namespace Windows em C++/WinRT) para obter as declarações destas funções. - Para a estrutura winrt::clock, from_FILETIME/to_FILETIME foram preteridos em favor de from_file_time/to_file_time.
- APIs simplificadas que aceitam parâmetros IBuffer. A maioria das APIs prefere coleções ou arrays. Mas sentimos que devíamos facilitar a chamada de APIs que dependem do IBuffer. Esta atualização fornece acesso direto aos dados por trás de uma implementação do IBuffer . Utiliza a mesma convenção de nomenclatura de dados que a utilizada pelos contentores da Biblioteca Padrão C++. Essa convenção também evita colisões com nomes de metadados que convencionalmente começam por letra maiúscula.
- Geração de código melhorada: várias melhorias para reduzir o tamanho do código, melhorar o inlining e otimizar o cache de fábrica.
- Removi a recursão desnecessária. Quando a linha de comandos se refere a uma pasta, em vez de a uma específica
.winmd, acppwinrt.exeferramenta deixa de procurar recursivamente ficheiros.winmd. Acppwinrt.exeferramenta também lida agora com duplicados de forma mais inteligente, tornando-se mais resistente a erros do utilizador e a ficheiros mal formados.winmd. - Apontadores inteligentes e reforçados. Anteriormente, os revogadores de eventos falhavam em revogar quando atribuíam um novo valor por movimento. Isto ajudou a descobrir um problema em que as classes de ponteiros inteligentes não estavam a lidar de forma fiável com a autoatribuição; com origem no modelo da estrutura winrt::com_ptr. winrt::com_ptr foi corrigido, e os revogadores de eventos foram corrigidos para lidar corretamente com a semântica de movimento, de modo a que sejam revogados aquando da atribuição.
Important
Foram feitas alterações importantes à Extensão Visual Studio (VSIX) C++/WinRT, tanto na versão 1.0.181002.2, como mais tarde na versão 1.0.190128.4. Para detalhes destas mudanças e como afetam os seus projetos existentes, suporte ao Visual Studio para C++/WinRT e versões anteriores da extensão VSIX.
Isolamento dos ficheiros de cabeçalho do SDK do Windows
Isto pode ser uma alteração decisiva para o teu código.
Para compilar, o C++/WinRT já não depende dos ficheiros de cabeçalho do SDK do Windows. Os ficheiros de cabeçalho na biblioteca de tempo de execução C (CRT) e na C++ Standard Template Library (STL) também não incluem cabeçalhos do SDK do Windows. E isso melhora a conformidade com as normas, evita dependências inadvertidas e reduz muito o número de macros contra os quais tem de se proteger.
Esta independência significa que o C++/WinRT é agora mais portátil e compatível com os padrões, e aumenta a possibilidade de se tornar um compilador cruzado e uma biblioteca multiplataforma. Também significa que os cabeçalhos C++/WinRT não são afetados negativamente por macros.
Se anteriormente deixou para C++/WinRT incluir quaisquer cabeçalhos do Windows no seu projeto, agora terá de os incluir você mesmo. É, em todo o caso, sempre uma boa prática incluir explicitamente os ficheiros de cabeçalho de que necessita, e não deixar que outra biblioteca os inclua em seu lugar.
Atualmente, as únicas exceções ao isolamento de ficheiros de cabeçalho do SDK do Windows são para intrínsecos e números. Não existem problemas conhecidos com estas últimas dependências.
No teu projeto, podes reativar a interoperabilidade com os cabeçalhos do SDK do Windows se precisares. Pode, por exemplo, querer implementar uma interface COM (enraizada no IUnknown). Para esse exemplo, inclua unknwn.h antes de incluir quaisquer cabeçalhos C++/WinRT. Ao fazê-lo, a biblioteca base C++/WinRT permite que vários hooks suportem 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 cabeçalhos do SDK do Windows que declarem tipos e/ou funções que pretende chamar.
Como redirecionar o seu projeto C++/WinRT para uma versão posterior do Windows SDK
O método para redirecionar o seu projeto, que provavelmente resultará no menor número de problemas com compiladores e linkadores, é também o mais trabalhoso. Esse método envolve criar um novo projeto (direcionado para a versão do SDK do Windows à sua escolha) e depois copiar ficheiros para o novo projeto a partir do antigo. Haverá secções dos teus ficheiros antigos .vcxproj e .vcxproj.filters que podes simplesmente copiar para evitar adicionar ficheiros no Visual Studio.
No entanto, existem duas outras formas de redirecionar o seu projeto no Visual Studio.
- Vá para a propriedade do projeto General>Windows SDK Version e selecione All Configurations e All Platforms. Defina a versão do SDK do Windows para a versão que pretende atingir.
- No Explorador de Soluções, clique com o botão direito no nó do projeto, clique em Redirecionar Projetos, escolha a(s) versão(ões) que deseja direcionar e depois clique em OK.
Se encontrar algum erro no compilador ou no linker após usar qualquer um destes dois métodos, pode tentar limpar a solução (Construir>Solução Limpa e/ou eliminar manualmente todas as pastas e ficheiros temporários) antes de tentar compilar novamente.
Se o compilador de C++ produzir "erro C2039: 'IUnknown': não é membro do ''namespace global''", adicione #include <unknwn.h> na parte superior do ficheiro pch.h (antes de incluir quaisquer cabeçalhos C++/WinRT).
Também podes precisar de acrescentar #include <hstring.h> depois disso.
Se o linker C++ produzir "erro LNK2019: símbolo externo não resolvido _WINRT_CanUnloadNow@0 referenciado na função _VSDesignerCanUnloadNow@0", então pode resolver isso adicionando #define _VSDESIGNER_DONT_LOAD_AS_DLL ao seu pch.h ficheiro.
Windows developer