Compartilhar via


Passo a passo: criar e usar sua própria biblioteca de vínculo dinâmico (C++)

Este passo a passo explica como usar o IDE do Visual Studio para criar sua própria DLL (biblioteca de vínculo dinâmico) escrita no Microsoft C++ (MSVC) e como usar a DLL de outro aplicativo C++. As DLLs, também conhecidas como bibliotecas compartilhadas em sistemas operacionais baseados em UNIX, são um dos tipos mais úteis de componentes do Windows. Você pode usá-los para compartilhar código e recursos e reduzir o tamanho de seus aplicativos. As DLLs podem até facilitar o serviço e estender seus aplicativos.

Neste passo a passo, você cria uma DLL que implementa algumas funções matemáticas. Em seguida, você cria um aplicativo de console que usa as funções da DLL. Você também tem uma introdução a algumas das técnicas de programação e convenções usadas em DLLs do Windows.

Este passo a passo aborda as seguintes etapas:

  • Crie um projeto de DLL no Visual Studio.
  • Adicione funções e variáveis exportadas à DLL.
  • Crie um projeto de aplicativo de console no Visual Studio.
  • Use as funções e variáveis importadas da DLL no aplicativo de console.
  • Execute o aplicativo concluído.

Como uma biblioteca vinculada estaticamente, uma DLL exporta variáveis, funções e recursos por nome. Um aplicativo cliente importa os nomes para usar essas variáveis, funções e recursos. Ao contrário de uma biblioteca vinculada estaticamente, o Windows conecta as importações em seu aplicativo às exportações em uma DLL no tempo de carregamento ou em tempo de execução, em vez de conectá-las no momento do link. O Windows requer informações extras que não fazem parte do modelo de compilação C++ padrão para fazer essas conexões. O compilador MSVC implementa algumas extensões específicas da Microsoft para C++ para fornecer essas informações extras. Explicamos essas extensões à medida que avançamos.

Este passo a passo cria duas soluções do Visual Studio: uma que cria a DLL e outra que cria o aplicativo cliente. A DLL usa a convenção de chamada C. Isso pode ser chamado por aplicativos escritos em outras linguagens de programação, desde que a plataforma, as convenções de chamada e as convenções de vinculação concordem. O aplicativo cliente usa a vinculação implícita, em que o Windows vincula o aplicativo à DLL no tempo de carregamento. Essa vinculação permite que o aplicativo chame as funções fornecidas por DLL, assim como as funções em uma biblioteca vinculada estaticamente.

Este passo a passo não abrange algumas situações comuns. O código não mostra o uso de DLLs C++ por outras linguagens de programação. Ele não mostra como criar uma DLL somente de recurso ou como usar a vinculação explícita para carregar DLLs em tempo de execução em vez de no momento da carga. Tenha certeza de que você pode usar o MSVC e o Visual Studio para fazer todas essas coisas.

Mesmo que o código da DLL seja escrito em C++, usamos interfaces de estilo C para as funções exportadas. Há dois motivos principais para isso: primeiro, muitos outros idiomas dão suporte a importações de funções de estilo C. O aplicativo cliente não precisa ser escrito em C++. Em segundo lugar, evita algumas armadilhas comuns relacionadas a classes exportadas e funções de membro. É fácil cometer erros difíceis de diagnosticar ao exportar classes, já que tudo o que se refere dentro de uma declaração de classe precisa ter uma instanciação que também seja exportada. Essa restrição se aplica a DLLs, mas não a bibliotecas estáticas. Se suas classes forem estilos de dados simples e antigos, você não deverá encontrar esse problema.

Para obter links para obter mais informações sobre DLLs, consulte Criar DLLs C/C++ no Visual Studio. Para obter mais informações sobre vinculação implícita e vinculação explícita, consulte Determine qual método de vinculação usar. Para obter informações sobre como criar DLLs C++ para uso com linguagens de programação que usam convenções de vinculação de linguagem C, consulte Exportando funções C++ para uso em executáveis de linguagem C. Para obter informações sobre como criar DLLs para uso com linguagens .NET, consulte Como chamar funções DLL de aplicativos do Visual Basic.

Pré-requisitos

  • Microsoft Windows 7 ou posterior. Recomendamos a versão mais recente do Windows para a melhor experiência de desenvolvimento.
  • Visual Studio. Para saber como baixar e instalar o Visual Studio, consulte Instalar o Visual Studio. Ao executar o instalador, verifique se o desenvolvimento de área de trabalho com C++ está marcado. Não se preocupe se você não instalou essa carga de trabalho quando instalou o Visual Studio. Você pode executar o instalador novamente e instalá-lo agora.

    Captura de tela do Instalador do Visual Studio, desenvolvimento para desktop com workload de C++.

  • Visual Studio. Para obter informações sobre como baixar e instalar o Visual Studio 2015, consulte Instalar o Visual Studio 2015. Use uma instalação personalizada para instalar o compilador e as ferramentas do C++, pois elas não estão instaladas por padrão.
  • Uma compreensão dos conceitos básicos do uso do IDE do Visual Studio. Se você já usou aplicativos da área de trabalho do Windows antes, provavelmente poderá acompanhar. Para obter uma introdução, consulte o tour de recursos do IDE do Visual Studio.

  • Alguma familiaridade com a linguagem C++. Não se preocupe, não fazemos nada muito complicado.

Observação

Este passo a passo pressupõe que você esteja usando o Visual Studio 2017 versão 15.9 ou posterior. Algumas versões anteriores do Visual Studio 2017 tinham defeitos nos modelos de código ou usavam caixas de diálogo de interface do usuário diferentes. Para evitar problemas, use o Instalador do Visual Studio para atualizar o Visual Studio 2017 para a versão 15.9 ou posterior.

Criar o projeto de DLL

No seguinte conjunto de tarefas, você cria um projeto para sua DLL, adiciona código e cria-o. Para começar, inicie o IDE do Visual Studio e entre se necessário. As instruções variam ligeiramente dependendo de qual versão do Visual Studio você está usando. Para ver as etapas da sua versão preferencial do Visual Studio, use o seletor de versão localizado na parte superior do sumário nesta página.

Para criar um projeto de DLL no Visual Studio

  1. Na barra de menus, escolha Arquivo>Novo>Projeto para abrir a caixa de diálogo Criar um projeto.

    Captura de tela da caixa de diálogo Criar um novo projeto com o modelo de biblioteca de vínculo dinâmico realçado.

  2. Na parte superior da caixa de diálogo, defina Idioma como C++, defina Plataforma para Windows e defina o tipo de projeto como Biblioteca.

  3. Na lista filtrada de tipos de projeto, selecione DLL (Biblioteca de vínculo dinâmico) e escolha Avançar.

  4. Na página Configurar seu novo projeto , insira MathLibrary na caixa de nome do Projeto para especificar um nome para o projeto. Deixe os valores de nome de solução e localização padrão. Defina a solução para criar uma nova solução. Desmarque Colocar a solução e o projeto no mesmo diretório se estiver marcado.

  5. Escolha o botão Criar para criar o projeto.

Quando a solução é criada, você pode ver o projeto gerado e os arquivos de origem na janela do Gerenciador de Soluções no Visual Studio.

Captura de tela da janela Gerenciador de Soluções com o projeto MathLibrary realçado.

Para criar um projeto de DLL no Visual Studio 2017

  1. Na barra de menus, escolha Arquivo>Novo>Projeto para abrir a caixa de diálogo Novo Projeto.

  2. No painel esquerdo da caixa de diálogo Novo Projeto , selecione Instalado>Visual C++>Área de Trabalho do Windows. No painel central, selecione Biblioteca de Vínculo Dinâmico (DLL). Insira MathLibrary na caixa Nome para especificar um nome para o projeto. Deixe os valores de nome de solução e localização padrão. Defina a solução para criar uma nova solução. Verifique Criar diretório para a solução se estiver não marcado.

    Captura de tela da caixa de diálogo Novo Projeto no Visual Studio 2017 mostrando a Biblioteca de Matemática na caixa de texto Nome.

  3. Escolha o botão OK para criar o projeto.

Quando a solução é criada, você pode ver o projeto gerado e os arquivos de origem na janela do Gerenciador de Soluções no Visual Studio.

Captura de tela da janela Gerenciador de Soluções no Visual Studio 2017 com a Biblioteca de Matemática realçada.

Para criar um projeto de DLL no Visual Studio 2015 e versões mais antigas

  1. Na barra de menus, escolha Arquivo>Novo>Projeto.

  2. No painel esquerdo da caixa de diálogo Novo Projeto, expanda> e selecione Visual C++e, no painel central, selecione Aplicativo do Console Win32. Insira MathLibrary na caixa de edição Nome para especificar um nome para o projeto. Deixe os valores de nome de solução e localização padrão. Defina a solução para criar uma nova solução. Verifique Criar diretório para a solução se esta opção estiver desmarcada.

    Captura de tela da caixa de diálogo Novo Projeto no Visual Studio 2015 mostrando MathLibrary na caixa de texto Nome.

  3. Escolha o botão OK para ignorar a caixa de diálogo Novo Projeto e iniciar o Assistente de Aplicativo Win32.

    Captura de tela da página Visão geral do Assistente de Aplicativo Win32.

  4. Escolha o botão Avançar. Na página Configurações do Aplicativo , em Tipo de aplicativo, selecione DLL.

    Captura de tela da página de Configurações do Assistente de Aplicações Win32.

  5. Escolha o botão Concluir para criar o projeto.

Quando o assistente concluir a solução, você poderá ver o projeto gerado e os arquivos de origem na janela do Gerenciador de Soluções no Visual Studio.

Captura de tela da janela Gerenciador de Soluções no Visual Studio 2015 com o MathLibrary realçado.

Neste momento, essa DLL não faz grande coisa. Em seguida, você criará um arquivo de cabeçalho para declarar as funções que sua DLL exporta e, em seguida, adicionará as definições de função à DLL para torná-la mais útil.

Para adicionar um arquivo de cabeçalho à DLL

  1. Para criar um arquivo de cabeçalho para suas funções, na barra de menus, escolha Project>Add New Item.

  2. Na caixa de diálogo Adicionar Novo Item , no painel esquerdo, selecione Visual C++. No painel central, selecione Arquivo de Cabeçalho (.h). Especifique MathLibrary.h como o nome do arquivo de cabeçalho.

    Captura de tela da caixa de diálogo Adicionar Novo Item com o modelo de Arquivo de Cabeçalho C++ selecionado e MathLibrary.h inserido na caixa de texto Nome.

  3. Escolha o botão Adicionar para gerar um arquivo de cabeçalho em branco, que é exibido em uma nova janela do editor.

    Captura de tela do arquivo MathLibrary.h vazio no editor.

  4. Substitua o conteúdo do arquivo de cabeçalho por este código:

    // MathLibrary.h - Contains declarations of math functions
    #pragma once
    
    #ifdef MATHLIBRARY_EXPORTS
    #define MATHLIBRARY_API __declspec(dllexport)
    #else
    #define MATHLIBRARY_API __declspec(dllimport)
    #endif
    
    // The Fibonacci recurrence relation describes a sequence F
    // where F(n) is { n = 0, a
    //               { n = 1, b
    //               { n > 1, F(n-2) + F(n-1)
    // for some initial integral values a and b.
    // If the sequence is initialized F(0) = 1, F(1) = 1,
    // then this relation produces the well-known Fibonacci
    // sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
    
    // Initialize a Fibonacci relation sequence
    // such that F(0) = a, F(1) = b.
    // This function must be called before any other function.
    extern "C" MATHLIBRARY_API void fibonacci_init(
        const unsigned long long a, const unsigned long long b);
    
    // Produce the next value in the sequence.
    // Returns true on success and updates current value and index;
    // false on overflow, leaves current value and index unchanged.
    extern "C" MATHLIBRARY_API bool fibonacci_next();
    
    // Get the current value in the sequence.
    extern "C" MATHLIBRARY_API unsigned long long fibonacci_current();
    
    // Get the position of the current value in the sequence.
    extern "C" MATHLIBRARY_API unsigned fibonacci_index();
    

Esse arquivo de cabeçalho declara algumas funções para produzir uma sequência de Fibonacci generalizada, considerando dois valores iniciais. Uma chamada para fibonacci_init(1, 1) gera a sequência de números Fibonacci familiar.

Observe as instruções de pré-processador na parte superior do arquivo. O novo modelo de projeto para um projeto de DLL adiciona <PROJECTNAME>_EXPORTS às macros de pré-processador definidas. Neste exemplo, o Visual Studio define MATHLIBRARY_EXPORTS quando seu projeto de DLL MathLibrary é criado.

Quando a MATHLIBRARY_EXPORTS macro é definida, a MATHLIBRARY_API macro define o __declspec(dllexport) modificador nas declarações de função. Esse modificador instrui o compilador e o vinculador a exportar uma função ou variável da DLL para uso de outros aplicativos. Quando MATHLIBRARY_EXPORTS é indefinido, por exemplo, quando o arquivo de cabeçalho é incluído por um aplicativo cliente, MATHLIBRARY_API aplica o __declspec(dllimport) modificador às declarações. Esse modificador otimiza a importação da função ou variável em um aplicativo. Para saber mais, confira dllexport, dllimport.

Para adicionar uma implementação à DLL

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no nó Arquivos de Origem e escolha Adicionar>Novo Item. Crie um novo .cpp arquivo chamado MathLibrary.cpp, da mesma forma que você adicionou um novo arquivo de cabeçalho na etapa anterior.

  2. Na janela do editor, selecione a guia MathLibrary.cpp se ela já estiver aberta. Caso contrário, no Gerenciador de Soluções, clique MathLibrary.cpp duas vezes na pasta Arquivos de Origem do projeto MathLibrary para abri-lo.

  3. No editor, substitua o conteúdo do MathLibrary.cpp arquivo pelo seguinte código:

    // MathLibrary.cpp : Defines the exported functions for the DLL.
    #include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier
    #include <utility>
    #include <limits.h>
    #include "MathLibrary.h"
    
    // DLL internal state variables:
    static unsigned long long previous_;  // Previous value, if any
    static unsigned long long current_;   // Current sequence value
    static unsigned index_;               // Current seq. position
    
    // Initialize a Fibonacci relation sequence
    // such that F(0) = a, F(1) = b.
    // This function must be called before any other function.
    void fibonacci_init(
        const unsigned long long a,
        const unsigned long long b)
    {
        index_ = 0;
        current_ = a;
        previous_ = b; // see special case when initialized
    }
    
    // Produce the next value in the sequence.
    // Returns true on success, false on overflow.
    bool fibonacci_next()
    {
        // check to see if we'd overflow result or position
        if ((ULLONG_MAX - previous_ < current_) ||
            (UINT_MAX == index_))
        {
            return false;
        }
    
        // Special case when index == 0, just return b value
        if (index_ > 0)
        {
            // otherwise, calculate next sequence value
            previous_ += current_;
        }
        std::swap(current_, previous_);
        ++index_;
        return true;
    }
    
    // Get the current value in the sequence.
    unsigned long long fibonacci_current()
    {
        return current_;
    }
    
    // Get the current index position in the sequence.
    unsigned fibonacci_index()
    {
        return index_;
    }
    
  1. Na janela do editor, selecione a guia para MathLibrary.cpp se ela já estiver aberta. Caso contrário, no Gerenciador de Soluções, clique duas vezes em MathLibrary.cpp na pasta Arquivos de Origem do projeto MathLibrary para abri-lo.

  2. No editor, substitua o conteúdo do MathLibrary.cpp arquivo pelo seguinte código:

    // MathLibrary.cpp : Defines the exported functions for the DLL.
    #include "stdafx.h" // use pch.h in Visual Studio 2019 and later
    #include <utility>
    #include <limits.h>
    #include "MathLibrary.h"
    
    // DLL internal state variables:
    static unsigned long long previous_;  // Previous value, if any
    static unsigned long long current_;   // Current sequence value
    static unsigned index_;               // Current seq. position
    
    // Initialize a Fibonacci relation sequence
    // such that F(0) = a, F(1) = b.
    // This function must be called before any other function.
    void fibonacci_init(
        const unsigned long long a,
        const unsigned long long b)
    {
        index_ = 0;
        current_ = a;
        previous_ = b; // see special case when initialized
    }
    
    // Produce the next value in the sequence.
    // Returns true on success, false on overflow.
    bool fibonacci_next()
    {
        // check to see if we'd overflow result or position
        if ((ULLONG_MAX - previous_ < current_) ||
            (UINT_MAX == index_))
        {
            return false;
        }
    
        // Special case when index == 0, just return b value
        if (index_ > 0)
        {
            // otherwise, calculate next sequence value
            previous_ += current_;
        }
        std::swap(current_, previous_);
        ++index_;
        return true;
    }
    
    // Get the current value in the sequence.
    unsigned long long fibonacci_current()
    {
        return current_;
    }
    
    // Get the current index position in the sequence.
    unsigned fibonacci_index()
    {
        return index_;
    }
    

Para verificar se tudo funciona até agora, compile a DLL. Para compilar, escolha Build>Build Solution na barra de menus. A DLL e a saída do compilador relacionada são colocadas em uma pasta chamada Debug diretamente abaixo da pasta da solução. Se você criar uma compilação de Release, a saída será colocada em uma pasta chamada Release. A saída deve ser algo como isto:

1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------
1>pch.cpp
1>dllmain.cpp
1>MathLibrary.cpp
1>Generating Code...
1>   Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------
1>stdafx.cpp
1>dllmain.cpp
1>MathLibrary.cpp
1>Generating Code...
1>   Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------
1>MathLibrary.cpp
1>dllmain.cpp
1>Generating Code...
1>   Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.pdb (Partial PDB)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

Parabéns, você criou uma DLL usando o Visual Studio! Em seguida, você criará um aplicativo cliente que usa as funções exportadas pela DLL.

Criar um aplicativo cliente que usa a DLL

Ao criar uma DLL, pense em como os aplicativos cliente podem usá-la. Para chamar as funções ou acessar os dados exportados por uma DLL, o código-fonte do cliente deve ter as declarações disponíveis no momento da compilação. No momento do link, o vinculador requer informações para resolver as chamadas de função ou acessos a dados. Uma DLL fornece essas informações em uma biblioteca de importação, um arquivo que contém informações sobre como localizar as funções e os dados, em vez do código real. E em tempo de execução, a DLL deve estar disponível para o cliente, em um local que o sistema operacional possa encontrar.

Seja ele próprio ou de terceiros, seu projeto de aplicativo cliente precisa de várias informações para usar uma DLL. Ele precisa encontrar os cabeçalhos que declaram as exportações de DLL, as bibliotecas de importação para o vinculador e a própria DLL. Uma solução é copiar todos esses arquivos para seu projeto cliente. Para DLLs de terceiros que dificilmente serão alteradas enquanto o cliente estiver em desenvolvimento, esse método pode ser a melhor maneira de usá-las. No entanto, quando você também cria a DLL, é melhor evitar a duplicação. Se você fizer uma cópia local de arquivos DLL que estão em desenvolvimento, poderá alterar acidentalmente um arquivo de cabeçalho em uma cópia, mas não na outra, ou usar uma biblioteca desatualizada.

Para evitar o código fora de sincronia, recomendamos que você defina o caminho de inclusão no seu projeto cliente para incluir os arquivos de cabeçalho DLL diretamente do seu projeto de DLL. Além disso, defina o caminho da biblioteca em seu projeto cliente para incluir as bibliotecas de importação de DLL do projeto DLL. Por fim, copie a DLL compilada do projeto DLL para o diretório de saída de compilação do cliente. Esta etapa permite que seu aplicativo cliente use o mesmo código DLL criado.

Para criar um aplicativo cliente no Visual Studio

  1. Na barra de menus, escolha Arquivo>Novo>Projeto para abrir a caixa de diálogo Criar um novo projeto .

  2. Na parte superior da caixa de diálogo, defina Linguagem como C++, Plataforma como Windows e Tipo de projeto como Console.

  3. Na lista filtrada de tipos de projeto, escolha Aplicativo de Console e, em seguida, escolha Avançar.

  4. Na página Configurar seu novo projeto , insira MathClient na caixa de nome do Projeto para especificar um nome para o projeto. Deixe os valores de nome de solução e localização padrão. Defina a solução para criar uma nova solução. Desmarque Colocar solução e projeto no mesmo diretório se estiver marcado.

    Captura de tela da caixa de diálogo Criar um novo projeto com a opção Aplicativo de Console realçada.

  5. Escolha o botão Criar para criar o projeto do cliente.

Um projeto de app de console básico foi criado para você. O nome do arquivo de origem principal é o mesmo que o nome do projeto que você inseriu anteriormente. Neste exemplo, ele é nomeado MathClient.cpp. Você pode compilá-lo, mas ele ainda não usa sua DLL.

Para criar um aplicativo cliente no Visual Studio 2017

  1. Para criar um aplicativo C++ que usa a DLL que você criou, na barra de menus, escolha Arquivo>Novo>Projeto.

  2. No painel esquerdo da caixa de diálogo Novo Projeto, selecione Área de Trabalho do Windows sob Instalado>Visual C++. No painel central, selecione Aplicativo de Console do Windows. Especifique o nome do projeto, MathClient, na caixa de edição Nome . Deixe os valores de nome de solução e localização padrão. Defina a solução para criar uma nova solução. Verifique Criar diretório para a solução se estiver desmarcado.

    Captura de tela da caixa de diálogo Novo Projeto com o Aplicativo de Console do Windows realçado e o Cliente de Matemática digitado na caixa de texto Nome.

  3. Escolha OK para criar o projeto do aplicativo cliente.

Um projeto de aplicativo mínimo de console é criado para você. O nome do arquivo de origem principal é o mesmo que o nome do projeto que você inseriu anteriormente. Neste exemplo, ele é nomeado MathClient.cpp. Você pode compilá-lo, mas ele ainda não usa sua DLL.

Para criar um aplicativo cliente no Visual Studio 2015

  1. Para criar um aplicativo C++ que usa a DLL que você criou, na barra de menus, escolha Arquivo>Novo>Projeto.

  2. No painel esquerdo da caixa de diálogo Novo Projeto, selecione Win32 emModelos Instalados>>Visual C++. No painel central, selecione Aplicativo de Console do Win32. Especifique o nome do projeto, MathClient, na caixa de edição Nome . Deixe os valores de nome de solução e localização padrão. Defina a solução para criar uma nova solução. Verifique Criar diretório para a solução se estiver desmarcado.

    Captura de tela da caixa de diálogo Novo Projeto com Aplicativo de Console do Win32 Visual C++ realçado e Math Client digitado na caixa de texto nome.

  3. Escolha o botão OK para ignorar a caixa de diálogo Novo Projeto e iniciar o Assistente de Aplicativo Win32. Na página Visão geral da caixa de diálogo Assistente de Aplicativo Win32 , escolha o botão Avançar .

  4. Na página Configurações do Aplicativo , em Tipo de aplicativo, selecione o aplicativo console se ele ainda não estiver selecionado.

  5. Escolha o botão Concluir para criar o projeto.

Quando o assistente é concluído, um projeto de aplicativo de console mínimo é criado para você. O nome do arquivo de origem principal é o mesmo que o nome do projeto que você inseriu anteriormente. Neste exemplo, ele é nomeado MathClient.cpp. Você pode compilá-lo, mas ele ainda não usa sua DLL.

Em seguida, para chamar as funções MathLibrary em seu código-fonte, seu projeto deve incluir o MathLibrary.h arquivo. Você pode copiar esse arquivo de cabeçalho para o projeto do aplicativo cliente e adicioná-lo ao projeto como um item existente. Esse método pode ser uma boa opção para bibliotecas de terceiros. No entanto, se você estiver trabalhando no código para sua DLL e seu cliente ao mesmo tempo, os arquivos de cabeçalho poderão sair da sincronização. Para evitar esse problema, defina o caminho Diretórios de Inclusão Adicionais em seu projeto para incluir o caminho para o cabeçalho original.

Para adicionar o cabeçalho DLL ao caminho de inclusão

  1. Clique com o botão direito do mouse no nó MathClient no Gerenciador de Soluções para abrir a caixa de diálogo Páginas de Propriedades .

  2. Na caixa suspensa Configuração , selecione Todas as Configurações se ela ainda não estiver selecionada.

  3. No painel esquerdo, selecione Propriedades de >C/C++>Geral.

  4. No painel de propriedades, selecione o controle suspenso ao lado da caixa de edição Diretórios de Inclusão Adicionais e escolha Editar.

    Captura de tela da caixa de diálogo Páginas de Propriedades mostrando o comando Editar na lista suspensa da propriedade Incluir Diretórios Adicionais.

  5. Clique duas vezes no painel superior da caixa de diálogo Incluir Diretórios Adicionais para habilitar um controle de edição. Ou escolha o ícone de pasta para criar uma nova entrada.

  6. No controle de edição, especifique o caminho até o local do arquivo cabeçalho MathLibrary.h. Você pode escolher o controle de reticências (...) para navegar até a pasta correta.

    Você também pode inserir um caminho relativo dos arquivos de origem do cliente para a pasta que contém os arquivos de cabeçalho DLL. Se você seguiu as instruções para colocar seu projeto cliente em uma solução separada da DLL, o caminho relativo deverá ter esta aparência:

    ..\..\MathLibrary\MathLibrary

    Se os projetos de DLL e cliente estiverem na mesma solução, o caminho relativo poderá ser semelhante a este:

    ..\MathLibrary

    Quando a DLL e os projetos cliente estiverem em outras pastas, ajuste o caminho relativo para corresponder. Ou utilize o controle de reticências para procurar a pasta.

    Captura de tela da caixa de diálogo Incluir Diretórios Adicionais mostrando o caminho relativo para o diretório MathLibrary.

  7. Depois de inserir o caminho para o arquivo de cabeçalho na caixa de diálogo Incluir Diretórios Adicionais , escolha o botão OK . Na caixa de diálogo Páginas de Propriedades , escolha o botão OK para salvar suas alterações.

Agora você pode incluir o MathLibrary.h arquivo e usar as funções que ele declara em seu aplicativo cliente. Substitua os conteúdos de MathClient.cpp usando este código:

// MathClient.cpp : Client app for MathLibrary DLL.
// #include "pch.h" Uncomment for Visual Studio 2017 and earlier
#include <iostream>
#include "MathLibrary.h"

int main()
{
    // Initialize a Fibonacci relation sequence.
    fibonacci_init(1, 1);
    // Write out the sequence values until overflow.
    do {
        std::cout << fibonacci_index() << ": "
            << fibonacci_current() << std::endl;
    } while (fibonacci_next());
    // Report count of values written before overflow.
    std::cout << fibonacci_index() + 1 <<
        " Fibonacci sequence values fit in an " <<
        "unsigned 64-bit integer." << std::endl;
}

Esse código pode ser compilado, mas não vinculado. Se você compilar o aplicativo cliente agora, a lista de erros mostrará vários erros LNK2019. Isso ocorre porque seu projeto está perdendo algumas informações: você ainda não especificou que seu projeto tem uma dependência na MathLibrary.lib biblioteca. E você não disse ao vinculador como localizar o MathLibrary.lib arquivo.

Para corrigir esse problema, você pode copiar o arquivo de biblioteca diretamente para o projeto do aplicativo cliente. O vinculador localizaria e o usaria automaticamente. No entanto, se a biblioteca e o aplicativo cliente estiverem em desenvolvimento, isso poderá levar a alterações em uma cópia que não são mostradas na outra. Para evitar esse problema, você pode definir a propriedade Dependências Adicionais para informar ao sistema de build do qual seu projeto depende MathLibrary.lib. Além disso, você pode definir um caminho de Diretórios de Biblioteca Adicionais em seu projeto para incluir o caminho para a biblioteca original ao vincular.

Para adicionar a biblioteca de importação de DLL ao seu projeto

  1. Clique com o botão direito do mouse no nó MathClient no Gerenciador de Soluções e escolha Propriedades para abrir a caixa de diálogo Páginas de Propriedades .

  2. Na caixa suspensa Configuração , selecione Todas as Configurações se ela ainda não estiver selecionada. Ele garante que todas as alterações de propriedade se apliquem a ambas as compilações Debug e Release.

  3. No painel esquerdo, selecione Propriedades de Configuração>Vinculador>Entrada. No painel de propriedades, selecione o controle suspenso ao lado da caixa de edição Dependências Adicionais e escolha Editar.

    Captura de tela da caixa de diálogo Páginas de Propriedades sob Entrada que exibe o comando Editar na lista suspensa da propriedade Dependências Adicionais.

  4. Na caixa de diálogo Dependências Adicionais , adicione MathLibrary.lib à lista no controle de edição superior.

    Captura de tela da caixa de diálogo Dependências Adicionais mostrando o arquivo MathLibrary.lib.

  5. Escolha OK para voltar à caixa de diálogo Páginas de Propriedades .

  6. No painel esquerdo, selecione Configuration Properties>Linker>General. No painel de propriedades, selecione o menu suspenso ao lado da caixa de edição Diretórios de Biblioteca Adicionais e escolha Editar.

    Captura de tela da caixa de diálogo Páginas de Propriedades na seção Geral que mostra o comando Editar na lista suspensa da propriedade

  7. Clique duas vezes no painel superior da caixa de diálogo Diretórios de Biblioteca Adicionais para habilitar um controle de edição. No controle de edição, especifique o caminho para o local do MathLibrary.lib arquivo. Por padrão, ele está em uma pasta chamada Depurar diretamente na pasta da solução DLL. Se você criar um build de versão, o arquivo será colocado em uma pasta chamada Versão. Você pode usar a $(IntDir) macro para que o vinculador possa encontrar sua DLL, independentemente do tipo de build que você criar. Se você seguiu as instruções para colocar seu projeto cliente em uma solução separada do projeto DLL, o caminho relativo deverá ter esta aparência:

    ..\..\MathLibrary\$(IntDir)

    Se a DLL e os projetos cliente estiverem em outros locais, ajuste o caminho relativo para corresponder.

    Captura de tela da caixa de diálogo Diretórios de Biblioteca Adicionais.

  8. Depois de inserir o caminho para o arquivo de biblioteca na caixa de diálogo Diretórios adicionais da biblioteca , escolha o botão OK para voltar para a caixa de diálogo Páginas de Propriedades . Escolha OK para salvar as alterações de propriedade.

Seu aplicativo cliente agora pode compilar e vincular com êxito, mas ainda não tem tudo o que precisa para ser executado. Quando o sistema operacional carrega seu aplicativo, ele procura a DLL de MathLibrary. Se ele não conseguir encontrar a DLL em determinados diretórios do sistema, no caminho do ambiente ou no diretório do aplicativo local, a carga falhará. Dependendo do sistema operacional, você verá uma mensagem de erro como esta:

Captura de tela da caixa de diálogo de erro, DLL MathLibrary não encontrada.

Uma maneira de evitar esse problema é copiar a DLL para o diretório que contém o executável do cliente como parte do processo de build. Você pode adicionar um evento pós-build ao seu projeto para adicionar um comando que copia a DLL ao diretório de saída de build. O comando especificado aqui copia a DLL somente se ela estiver ausente ou tiver sido alterada. Ele utiliza macros para copiar de e para os locais de depuração ou liberação, com base na configuração de compilação.

Para copiar a DLL em um evento de pós-compilação

  1. Clique com o botão direito do mouse no nó MathClient no Gerenciador de Soluções e escolha Propriedades para abrir a caixa de diálogo Páginas de Propriedades .

  2. Na caixa suspensa Configuração , selecione Todas as Configurações se ela ainda não estiver selecionada.

  3. No painel esquerdo, selecione Propriedades de Configuração>Eventos de Build>Evento Pós-Build.

  4. No painel de propriedades, selecione o controle de edição no campo Linha de Comando . Se você seguiu as instruções para colocar seu projeto cliente em uma solução separada do projeto DLL, insira este comando:

    xcopy /y /d "..\..\MathLibrary\$(IntDir)MathLibrary.dll" "$(OutDir)"

    Se a DLL e os projetos de cliente estiverem em outros diretórios, ajuste o caminho relativo para a DLL para corresponder.

    Captura de tela da caixa de diálogo da Página de Propriedades mostrando a propriedade da linha de comando do evento de pós-compilação.

  5. Escolha o botão OK para salvar suas alterações nas propriedades do projeto.

Agora seu aplicativo cliente tem tudo o que precisa para compilar e executar. Compile o aplicativo escolhendo Compilar>Compilar Solução na barra de menus. A janela Saída no Visual Studio deve ter algo semelhante ao exemplo a seguir, dependendo da sua versão do Visual Studio:

1>------ Build started: Project: MathClient, Configuration: Debug Win32 ------
1>MathClient.cpp
1>MathClient.vcxproj -> C:\Users\username\Source\Repos\MathClient\Debug\MathClient.exe
1>1 File(s) copied
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

Parabéns, você criou um aplicativo que chama funções em sua DLL. Agora, execute seu aplicativo para ver o que ele faz. Na barra de menus, escolha Depurar>Iniciar Sem Depuração. O Visual Studio abre uma janela de comando para o programa ser executado. A última parte da saída deve ser semelhante a:

Captura de tela da saída da janela de comando ao iniciar o aplicativo cliente sem depuração.

Pressione qualquer tecla para ignorar a janela de comando.

Agora que você criou uma DLL e um aplicativo cliente, você pode experimentar. Tente definir pontos de interrupção no código do aplicativo cliente e execute o aplicativo no depurador. Veja o que acontece quando você entra em uma chamada de biblioteca. Adicione outras funções à biblioteca ou escreva outro aplicativo cliente que use sua DLL.

Ao implantar seu aplicativo, você também deve implantar as DLLs que ele usa. A maneira mais simples de tornar as DLLs que você cria ou que você inclui de terceiros está disponível é colocá-las no mesmo diretório que seu aplicativo. Ela é conhecida como implantação local do aplicativo. Para obter mais informações sobre a implantação, consulte Implantação no Microsoft C++.

Consulte também