Tutorial: Instalar dependências nativas numa aplicação CLR

C++/CLI é uma tecnologia que permite combinar classes .NET com tipos nativos de C++ para criar bibliotecas e aplicações que aceitam código C++ e o tornam acessível a programas .NET.

Pode usar vcpkg em combinação com C++/CLI para instalar e consumir dependências de C++ nos seus projetos direcionados ao Common Language Runtime (CLR).

Neste tutorial, vai aprender a:

Prerequisites

Construa um exemplo de C++/CLI

Neste tutorial, vamos partir de uma aplicação C++/CLI existente e adicionar um dependente de C++ instalado com vcpkg. Os comandos deste tutorial assumem que os estás a executar num PowerShell de Desenvolvedor para Visual Studio.

1 - Clonar o repositório de exemplos

O primeiro passo é obter uma cópia da aplicação de exemplos C++/CLI no repositório de samples .NET. A aplicação de exemplo C++/CLI encontra-se na core/interop/cpp-cli pasta.

git clone https://github.com/dotnet/samples

2 - Navegar até à pasta de aplicação de exemplo

cd samples/core/interpo/cpp-cli

2 - Verificar se o projeto se constrói e corre corretamente

O repositório de exemplos contém uma solução com quatro projetos:

  • Managed Library: Uma biblioteca C# para .NET
  • MixedLibrary: Uma biblioteca que mistura código nativo C++ e código .NET da Managed Library
  • NativeApp: Uma aplicação C++ que consome código .NET da MixedLibrary
  • ManagedApp: Uma aplicação C# que consome código C++ da MixedLibrary

Execute o seguinte comando para construir os projetos da solução:

msbuild CPP-CLI.sln -restore

Se a compilação falhar, certifique-se de que instalou os componentes necessários para o Visual Studio listados na secção de Pré-requisitos, e que cumpre os requisitos mínimos do .NET 5.0 SDK ou posterior e do Visual Studio 2019 16.8 ou posterior da aplicação de exemplo.

Depois de compilado, podes executar ManagedApp.exe

./bin/Debug/x64/ManagedApp.exe

O programa produz a seguinte saída:

=== Managed class ===
Hello from ManagedClass in MixedLibrary
Hello from NativeClass in MixedLibrary
-- message: from managed app!

=== P/Invoke ===
Hello from NativeEntryPoint_CallNative in MixedLibrary
Hello from NativeClass in MixedLibrary
-- message: from managed app!

3 - Abrir o projeto no Visual Studio

Nos próximos passos, vamos modificar a biblioteca para usar fmt para imprimir mensagens na consola. A biblioteca fmt será instalada via vcpkg e associada nos projetos que a utilizam.

Para editar os ficheiros de origem, abra a solução CPP-CLI.sln em Visual Studio:

start CPP-CLI.sln

Depois de a solução ser aberta no Visual Studio, pode receber um pedido para redirecionar o projeto para as versões mais recentes. Pode clicar em OK para atualizar a versão do SDK do Windows e o conjunto de ferramentas da plataforma para a versão mais recente.

Redirecionar projeto existente

a versão de destino do SDK do Windows do projeto e a versão do Conjunto de Ferramentas da Plataforma para a versão mais recente.

Adicionar uma dependência nativa de C++

De seguida, faremos as seguintes alterações ao projeto MixedLibrary.

  • Adicione um ficheiro de manifesto do vcpkg para obter fmt.
  • Ativa o vcpkg no projeto.
  • Modifica o NativeClass::Hello para usar fmt para imprimir mensagens.

1 - Criar um manifesto vcpkg

Clique com o botão direito no projeto NativeLibrary e clique em Adicionar > Novo Item no menu contextual.

Nomeie o novo item vcpkg.json, este é o ficheiro manifesto vcpkg, e certifique-se de que o ficheiro é criado na raiz da pasta do projeto.

2 - Adicionar fmt como dependência

Abra o vcpkg.json ficheiro e edite o seu conteúdo para corresponder ao seguinte:

{
  "dependencies": [ "fmt" ]
}

Se o ficheiro manifesto vcpkg estiver localizado no local certo e tentar construir o projeto, receberá o seguinte aviso:

The vcpkg manifest was disabled, but we found a manifest file in samples\core\interop\cpp-cli\MixedLibrary\. You may want to enable vcpkg manifests in your properties page or pass /p:VcpkgEnableManifest=true to the msbuild invocation.

3 - Ativar vcpkg nas propriedades do MixedLibrary

Abra a página de propriedades da MixedLibrary clicando com o botão direito no projeto e clicando na opção Propriedades.

Alterar as seguintes propriedades na secção vcpkg:

  • Utilizar o Vcpkg definido como Sim
  • Utilizar manifest do Vcpkg definido como Sim
  • Instal Vcpkg Dependencies definido para Sim
  • Use o AutoLink definido para Sim
  • Implementar DLLs localmente na aplicação definido como Sim

Propriedades do projeto MixedLibrary

Necessário para ativar o VCPKG

Com estas alterações, o Visual Studio irá agora ler o vcpkg.json ficheiro e instalar automaticamente as dependências contidas no manifesto antes de construir o projeto.

Enquanto estivermos na página Propriedades, também queremos ativar a opção /utf-8 para que fmt seja compilado corretamente.

Na subsecção Linha de Comandos das definições de C/C++, edite as Opções Adicionais para incluir /utf-8 no

Por fim, clique em OK para fechar a página de Propriedades.

4 - Verificar se o vcpkg está a funcionar

Se tudo estiver corretamente configurado, o Visual Studio irá invocar o vcpkg para instalar as suas dependências antes de construir o projeto MixedLibrary.

1>Installing vcpkg dependencies to  C:\path\to\samples\core\interop\cpp-cli\MixedLibrary\vcpkg_installed\x64-windows\
1>"C:\path\to\vcpkg\vcpkg.exe" install --x-wait-for-lock --triplet "x64-windows" --vcpkg-root "C:\path\to\vcpkg\" "--x-manifest-root=C:\path\to\samples\core\interop\cpp-cli\MixedLibrary\" "--x-install-root=C:\path\to\samples\core\interop\cpp-cli\MixedLibrary\vcpkg_installed\x64-windows\"

Se não vir a saída do vcpkg, ou se fmt falhar na compilação, certifique-se de que seguiu corretamente os passos acima, incluindo adicionar /utf-8 em Opções Adicionais, em C/C++ > Linha de Comando.

4 - Modificar o código-fonte do projeto

Por fim, queremos modificar o ficheiro MixedLibrary.cpp para usar fmt para imprimir mensagens para a consola. Faça as seguintes alterações ao código-fonte:

1 - Incluir o fmt/printf.h cabeçalho (na linha 5).

#include <iostream>
#include <vcclr.h>
#include <fmt/printf.h>

2 - Modificar a função NativeClass::Hello para usar fmt::println (na linha 44).

void MixedLibrary::NativeClass::Hello(const wchar_t *msg)
{
    auto ws = std::wstring(msg);
    auto str = std::string(ws.length(), 0);
    std::transform(ws.begin(), ws.end(), std::back_inserter(str), [](wchar_t c) { return static_cast<char>(c); });
    fmt::println("Hello from NativeClass in MixedLibrary");
    fmt::println("-- message: {}", str);
    fmt::println("-- printed using FMT version {}", FMT_VERSION);
}

Criar a aplicação

A NativeClass::Hello função é usada no projeto ManagedApp para imprimir uma mensagem na consola usando código C++. As alterações acima fazem com que a biblioteca fmt seja utilizada na aplicação CLR.

Não são necessárias alterações ao projeto da aplicação, basta construir e executar o projeto ManagedApp.

A saída do programa deve ser semelhante a esta:

=== Managed class ===
Hello from ManagedClass in MixedLibrary
Hello from NativeClass in MixedLibrary
-- message: from managed app!
-- printed using FMT version 110002

=== P/Invoke ===
Hello from NativeEntryPoint_CallNative in MixedLibrary
Hello from NativeClass in MixedLibrary
-- message: from managed app!
-- printed using FMT version 110002

Passos seguintes

Aprenda também sobre outras funcionalidades úteis: