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.
Há várias maneiras de usar o código C++ existente em projetos da Plataforma Universal do Windows (UWP). Algumas maneiras não exigem que o código seja recompilado com as extensões de componente (C++/CX) ativadas (ou seja, com a /ZW opção), e outras sim. Talvez seja necessário manter o código em C++ padrão ou preservar um ambiente de compilação Win32 clássico para algum código. Você ainda pode fazer isso, com opções de arquitetura apropriadas. Considere todo o seu código que contém a interface do usuário UWP e tipos que são expostos a chamadores C#, Visual Basic e JavaScript. Esse código deve estar em projetos de aplicativos Windows e projetos de componentes do Tempo de Execução do Windows. O código que você chama apenas de C++ (incluindo C++/CX) pode estar em um projeto que compila com a /ZW opção ou em um projeto C++ padrão. O código somente binário que não usa APIs não permitidas pode ser usado vinculando-o como uma biblioteca estática. Ou, você pode empacotá-lo com o aplicativo como conteúdo e carregá-lo em uma DLL.
Talvez a maneira mais fácil de executar seu programa de desktop no ambiente UWP seja usar as tecnologias Desktop Bridge. Eles incluem o Desktop App Converter, que empacotará seu aplicativo existente como um aplicativo UWP sem alterações de código necessárias. Para obter mais informações, consulte Desktop Bridge.
O restante deste artigo discute como portar bibliotecas C++ (DLLs e bibliotecas estáticas) para a Plataforma Universal do Windows. Talvez você queira portar seu código para que sua lógica C++ principal possa ser usada com vários aplicativos UWP.
Os aplicativos UWP são executados em um ambiente protegido. Como resultado, muitas chamadas de API Win32, COM e CRT que podem comprometer a segurança da plataforma não são permitidas. A /ZW opção do compilador pode detetar essas chamadas e gerar um erro. Você pode usar o Kit de Certificação de Aplicativo em seu aplicativo para detetar código que chama APIs não permitidas. Para obter mais informações, consulte Kit de Certificação de Aplicativos Windows.
Se o código-fonte estiver disponível para a biblioteca, você poderá tentar eliminar as chamadas de API não permitidas. Para obter uma lista de APIs que não são permitidas, consulte APIs Win32 e COM para aplicativos UWP e funções CRT não suportadas em aplicativos da Plataforma Universal do Windows. Algumas alternativas podem ser encontradas em Alternativas às APIs do Windows em aplicativos UWP.
Se você apenas tentar adicionar uma referência de um Projeto Universal do Windows a uma biblioteca de área de trabalho clássica, receberá uma mensagem de erro informando que a biblioteca não é compatível. Se for uma biblioteca estática, você pode vincular à sua biblioteca adicionando a biblioteca (.lib arquivo) à entrada do vinculador, da mesma forma que faria em um aplicativo Win32 clássico. Se apenas uma biblioteca binária estiver disponível, é a única opção. Uma biblioteca estática está vinculada ao executável do seu aplicativo. No entanto, uma DLL Win32 que você consome em um aplicativo UWP deve ser empacotada no aplicativo incluindo-a no projeto e marcando-a como Conteúdo. Para carregar uma DLL Win32 em um aplicativo UWP, você também precisa chamar LoadPackagedLibrary em vez de LoadLibrary ou LoadLibraryEx.
Se você tiver código-fonte para a DLL ou biblioteca estática, poderá recompilá-lo como um projeto UWP usando a /ZW opção de compilador. Em seguida, você pode adicionar uma referência a ele usando o Gerenciador de Soluções e usá-lo em aplicativos UWP C++. Vincule a DLL usando a biblioteca de exportação.
Para expor a funcionalidade a chamadores em outros idiomas, você pode converter a biblioteca em um componente do Tempo de Execução do Windows. Os componentes do Tempo de Execução do Windows diferem das DLLs comuns porque incluem metadados na forma de arquivos que descrevem o conteúdo de uma maneira que os consumidores de .winmd .NET e JavaScript exigem. Para expor elementos de API a outras linguagens, você pode adicionar construções C++/CX, como classes ref, e torná-las públicas. No Windows 10 e versões posteriores, recomendamos a biblioteca C++/WinRT em vez de C++/CX.
A discussão anterior não se aplica aos componentes COM, que devem ser tratados de forma diferente. Se você tiver um servidor COM em um EXE ou DLL, você pode usá-lo em um projeto Universal do Windows.
Empacote-o como um componente COM sem registro, adicione-o ao seu projeto como um arquivo de conteúdo e instancie-o usando CoCreateInstanceFromAppo . Para obter mais informações, consulte Usando Free-COM DLL no projeto C++ da Windows Store.
Se você quiser portar uma biblioteca COM existente para a UWP, também é possível convertê-la em um componente do Tempo de Execução do Windows. Recomendamos a biblioteca C++/WinRT para essas portas, mas também é possível usar a WRL (Biblioteca de Modelos C++ do Tempo de Execução do Windows). O WRL foi preterido e não suporta todos os recursos de ATL e OLE. Se essa porta é viável depende dos recursos de COM, ATL e OLE que seu componente requer.
Seja qual for o cenário de desenvolvimento escolhido, você deve estar ciente de várias definições de macro. Você pode usar essas macros em seu código, para compilar código condicionalmente em Win32 desktop clássico e UWP.
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PC_APP)
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
Essas instruções se aplicam, respectivamente, a aplicativos UWP, aplicativos da Loja do Windows Phone, ambos ou nenhum (somente área de trabalho Win32 clássica). Essas macros só estão disponíveis no Windows SDK 8.1 e posterior.
Este artigo contém os seguintes procedimentos:
Usando uma biblioteca estática C++ nativa em um aplicativo UWP
Portabilidade de uma biblioteca C++ para um componente do Tempo de Execução do Windows
Usando uma DLL Win32 em um aplicativo UWP
Para maior segurança e confiabilidade, os Aplicativos Universais do Windows são executados em um ambiente de tempo de execução restrito. Você não pode simplesmente usar qualquer DLL nativa da maneira que faria em um aplicativo clássico da área de trabalho do Windows. Se você tiver código-fonte para uma DLL, poderá portar o código para que ele seja executado na UWP. Você começa alterando algumas configurações de projeto e metadados de arquivo de projeto para identificar o projeto como um projeto UWP. Você recompilará o código da biblioteca usando a opção /ZW, que habilita C++/CX. Determinadas chamadas de API não são permitidas em aplicativos UWP devido a controles mais rígidos associados a esse ambiente. Para obter mais informações, consulte APIs Win32 e COM para aplicativos UWP.
Se tiveres uma DLL nativa que exporta funções usando __declspec(dllexport), podes chamar essas funções de uma aplicação UWP recompilando a DLL como um projeto UWP. Por exemplo, suponha que temos um projeto Win32 DLL chamado Giraffe que exporta algumas classes e seus métodos, com código como o seguinte arquivo de cabeçalho:
// giraffe.h
// Define GIRAFFE_EXPORTS when building this DLL
#pragma once
#ifdef GIRAFFE_EXPORTS
#define GIRAFFE_API __declspec(dllexport)
#else
#define GIRAFFE_API
#endif
GIRAFFE_API int giraffeFunction();
class Giraffe
{
int id;
Giraffe(int id_in);
friend class GiraffeFactory;
public:
GIRAFFE_API int GetID();
};
class GiraffeFactory
{
static int nextID;
public:
GIRAFFE_API GiraffeFactory();
GIRAFFE_API static int GetNextID();
GIRAFFE_API static Giraffe* Create();
};
E o seguinte arquivo de código:
// giraffe.cpp
#include "pch.h"
#include "giraffe.h"
Giraffe::Giraffe(int id_in) : id(id_in)
{
}
int Giraffe::GetID()
{
return id;
}
int GiraffeFactory::nextID = 0;
GiraffeFactory::GiraffeFactory()
{
nextID = 0;
}
int GiraffeFactory::GetNextID()
{
return nextID;
}
Giraffe* GiraffeFactory::Create()
{
return new Giraffe(nextID++);
}
int giraffeFunction();
Todo o resto no projeto (pch.h, dllmain.cpp) faz parte do modelo de projeto Win32 padrão. O código define a macro GIRAFFE_API, que resolve para __declspec(dllexport) quando GIRAFFE_EXPORTS é definido. Ou seja, é definido quando o projeto é criado como uma DLL, mas não quando um cliente usa o giraffe.h cabeçalho. Esta DLL pode ser usada em um projeto UWP sem alterar o código-fonte. Apenas algumas configurações e propriedades do projeto precisam ser alteradas.
O procedimento a seguir aplica-se quando se tem uma DLL nativa que expõe funções usando __declspec(dllexport).
Para portar uma DLL nativa para a UWP sem criar um novo projeto
Abra seu projeto DLL no Visual Studio.
Abra as propriedades do projeto para o projeto DLL e defina a configuração para todas as configurações.
Nas Propriedades do Projeto, na guia C/C++>General, defina Consumir Extensão do Tempo de Execução do Windows como Sim (/ZW). Esta propriedade permite extensões de componente (C++/CX).
No Gerenciador de Soluções, selecione o nó do projeto, abra o menu de atalho e escolha Descarregar projeto. Em seguida, abra o menu de atalho no nó do projeto descarregado e escolha editar o arquivo de projeto. Localize o
WindowsTargetPlatformVersionelemento e substitua-o pelos seguintes elementos.<AppContainerApplication>true</AppContainerApplication> <ApplicationType>Windows Store</ApplicationType> <WindowsTargetPlatformVersion>10.0.10156.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformMinVersion>10.0.10156.0</WindowsTargetPlatformMinVersion> <ApplicationTypeRevision>10.0</ApplicationTypeRevision>Feche o
.vcxprojarquivo, abra o menu de atalho novamente e escolha Recarregar projeto.O Gerenciador de Soluções agora identifica o projeto como um projeto Universal do Windows.
Verifique se o nome do arquivo de cabeçalho pré-compilado está correto. Na seção Cabeçalhos pré-compilados , talvez seja necessário alterar o arquivo de cabeçalho pré-compilado de
pch.hparastdafx.hou o contrário se vir um erro como este:erro C2857: A instrução '#include' especificada com a opção de linha de
/Ycpch.hcomando não foi encontrada no arquivo de origemO problema é que modelos de projeto mais antigos usam uma convenção de nomenclatura diferente para o arquivo de cabeçalho pré-compilado. O Visual Studio 2019 e versões posteriores dos projetos usam
pch.h.Construa o projeto. Você pode receber alguns erros sobre opções de linha de comando incompatíveis. Por exemplo, a opção agora obsoleta mas usada com frequência, Enable Minimal Rebuild (/Gm), é definida por padrão em muitos projetos C++ mais antigos e é incompatível com
/ZW.Algumas funções não estão disponíveis quando você compila para a Plataforma Universal do Windows. Você verá erros do compilador sobre quaisquer problemas. Corrija esses erros até ter uma compilação limpa.
Para usar a DLL em um aplicativo UWP na mesma solução, abra o menu de atalho para o nó do projeto UWP e escolha Adicionar>referência.
Em Solução de Projetos>, marque a caixa de seleção ao lado do projeto DLL e escolha o botão OK.
Inclua o(s) arquivo(s) de cabeçalho da biblioteca no arquivo do
pch.hseu aplicativo UWP.#include "..\Giraffe\giraffe.h"Adicione código como de costume no projeto UWP para invocar funções e criar tipos a partir da DLL.
MainPage::MainPage() { InitializeComponent(); GiraffeFactory gf; Giraffe* g = gf.Create(); int id = g->GetID(); }
Usando uma biblioteca estática C++ nativa em um aplicativo UWP
Você pode usar uma biblioteca estática C++ nativa em um projeto UWP, mas há algumas restrições e limitações a serem observadas. Comece lendo sobre bibliotecas estáticas em C++/CX. Você pode acessar o código nativo em sua biblioteca estática a partir de seu aplicativo UWP, mas não é recomendado criar tipos de referência públicos em tal biblioteca estática. Se compilares uma biblioteca estática com a opção /ZW, o bibliotecário (na verdade, o linker disfarçado) avisa:
LNK4264: arquivação de arquivo de objeto compilado com /ZW numa biblioteca estática; observar, no entanto, que ao criar tipos para o Windows Runtime, não é recomendável vincular a uma biblioteca estática que contenha metadados do Windows Runtime
No entanto, você pode usar uma biblioteca estática em um aplicativo UWP sem recompilá-la com /ZW. Sua biblioteca não pode declarar nenhum tipo de ref ou usar construções C++/CX. Mas, se o seu objetivo é apenas usar uma biblioteca de código nativo, então você pode fazê-lo seguindo estas etapas.
Para usar uma biblioteca estática C++ nativa em um projeto UWP
Nas propriedades do projeto para o projeto UWP, escolha Configuration Properties>Linker>Input no painel esquerdo. No painel direito, adicione o caminho à biblioteca na propriedade Dependências Adicionais . Por exemplo, para uma biblioteca no projeto que coloca a sua saída em
<SolutionFolder>\Debug\MyNativeLibrary\MyNativeLibrary.lib, adicione o caminho relativoDebug\MyNativeLibrary\MyNativeLibrary.lib.Adicione uma diretiva de inclusão para referenciar o ficheiro de cabeçalho no seu ficheiro
pch.h(se existir) ou em qualquer ficheiro.cpp, conforme necessário, e comece a adicionar código que utilize a biblioteca.#include "..\MyNativeLibrary\MyNativeLibrary.h"Não adicione uma referência no nó Referências no Gerenciador de Soluções. Esse mecanismo só funciona para componentes do Tempo de Execução do Windows.
Migrar uma biblioteca C++ para um Componente Runtime do Windows
Suponha que você queira consumir APIs nativas em uma biblioteca estática de um aplicativo UWP. Se você tiver o código-fonte da biblioteca nativa, poderá portar o código para um componente do Tempo de Execução do Windows. Não será mais uma biblioteca estática; você vai transformá-lo em uma DLL que você pode usar em qualquer aplicativo C++ UWP. Este procedimento descreve como criar um novo componente do Tempo de Execução do Windows que usa extensões C++/CX. Para obter informações sobre como criar um componente que usa C++/WinRT, consulte Componentes do Tempo de Execução do Windows com C++/WinRT.
Ao usar C++/CX, você pode adicionar tipos ref e outras construções C++/CX, que estão disponíveis para clientes em qualquer código de aplicativo UWP. Você pode acessar esses tipos em C#, Visual Basic ou JavaScript. O procedimento básico é:
- Criar um Projeto de Componente Windows Runtime (Windows Universal),
- copie o código da sua biblioteca estática para ele, e
- Resolva quaisquer erros do compilador causados pela
/ZWopção.
Para portar uma biblioteca C++ para um componente Windows Runtime
Crie um projeto do Componente do Tempo de Execução do Windows (Universal Windows).
Feche o projeto.
No Explorador de Arquivos do Windows, localize o novo projeto. Em seguida, localize o projeto de biblioteca C++ que contém o código que você deseja portar. Copie os arquivos de origem (arquivos de cabeçalho, arquivos de código e quaisquer outros recursos, inclusive em subdiretórios) do seu projeto de biblioteca C++. Cole-os na nova pasta do projeto, certificando-se de preservar a mesma estrutura de pastas.
Reabra o projeto do componente Windows Runtime. Abra o menu de atalho para o nó do projeto no Gerenciador de Soluções e escolha Adicionar>Item Existente.
Selecione todos os arquivos para adicionar do seu projeto original e escolha OK. Repita se necessário para subpastas.
Agora você pode ter algum código duplicado. Se houver mais de um cabeçalho pré-compilado (digamos, ambos
stdafx.hepch.h), escolha um para manter. Copie qualquer código necessário, como instruções include, para o código que você está mantendo. Em seguida, exclua o outro e, nas propriedades do projeto, em Cabeçalhos pré-compilados, verifique se o nome do arquivo de cabeçalho está correto.Se você alterou o arquivo para usar como cabeçalho pré-compilado, verifique se as opções de cabeçalho pré-compilado estão corretas para cada arquivo. Selecione cada
.cpparquivo por vez, abra sua janela de propriedades e certifique-se de que todos estão definidos como Usar (/Yu), exceto o cabeçalho pré-compilado, que deve ser definido como Criar (/Yc).Construa o projeto e resolva quaisquer erros. Esses erros podem ser causados pelo uso da
/ZWopção ou podem ser causados por uma nova versão do SDK do Windows. Ou podem refletir dependências, como arquivos de cabeçalho dos quais sua biblioteca depende ou diferenças nas configurações do projeto entre o projeto antigo e o novo.Adicione tipos ref públicos ao seu projeto ou converta tipos comuns em tipos ref. Use estes tipos para expor pontos de entrada na funcionalidade que você(s) deseja(m) chamar das aplicações UWP.
Teste o componente adicionando uma referência a ele de um projeto de aplicativo UWP e adicione algum código para chamar as APIs públicas que você criou.