Sdílet prostřednictvím


Procházení: Vytvořte a používejte vlastní dynamickou knihovnu (C++)

Tento podrobný návod vysvětluje, jak pomocí integrovaného vývojového prostředí sady Visual Studio vytvořit vlastní dynamickou knihovnu (DLL) napsanou v microsoft C++ (MSVC) a jak používat knihovnu DLL z jiné aplikace jazyka C++. Knihovny DLL, označované také jako sdílené knihovny v operačních systémech UNIX, jsou jedním z nejužitečnějších druhů komponent systému Windows. Můžete je použít ke sdílení kódu a prostředků a ke zmenšení velikosti aplikací. Knihovny DLL můžou dokonce usnadnit údržbu a rozšíření aplikací.

V tomto názorném postupu vytvoříte knihovnu DLL, která implementuje některé matematické funkce. Pak vytvoříte konzolovou aplikaci, která používá funkce z knihovny DLL. Seznámíte se také s některými programovacími technikami a konvencemi používanými v knihovnách DLL systému Windows.

Tento názorný postup popisuje následující kroky:

  • Vytvořte projekt DLL v prostředí Visual Studio.
  • Přidejte do knihovny DLL exportované funkce a proměnné.
  • Vytvořte projekt konzolové aplikace v sadě Visual Studio.
  • Použijte funkce a proměnné importované z knihovny DLL v konzolové aplikaci.
  • Spusťte dokončenou aplikaci.

Podobně jako staticky propojená knihovna exportuje knihovna DLL proměnné, funkce a prostředky podle názvu. Klientská aplikace naimportuje názvy tak, aby používaly tyto proměnné, funkce a prostředky. Na rozdíl od staticky propojené knihovny systém Windows připojí importy v aplikaci k exportům v knihovně DLL v době načtení nebo v době běhu místo jejich připojení v době propojení. Systém Windows vyžaduje další informace, které nejsou součástí standardního modelu kompilace C++, aby se tato připojení uskutečnila. Kompilátor MSVC implementuje některá rozšíření specifická pro Microsoft do jazyka C++, aby poskytl tyto dodatečné informace. Tato rozšíření vysvětlíme postupně.

Tento názorný postup vytvoří dvě řešení sady Visual Studio: jedno, které sestaví knihovnu DLL, a jedno, které sestaví klientskou aplikaci. Knihovna DLL používá konvenci volání jazyka C. Lze ji volat z aplikací napsaných v jiných programovacích jazycích, pokud platforma, konvence volání a propojení odpovídají. Klientská aplikace používá implicitní propojení, kdy Windows aplikaci při načítání propojí s knihovnou DLL. Toto propojení umožňuje aplikaci volat funkce dodané knihovnou DLL stejně jako funkce v staticky propojené knihovně.

Tento návod se nezabývá některými běžnými situacemi. Kód nezobrazuje použití knihoven DLL jazyka C++ jinými programovacími jazyky. Nezobrazuje, jak vytvořit knihovnu DLL jen pro prostředky nebo jak použít explicitní propojení pro načítání knihoven DLL při běhu programu, nikoli v době načítání. Ujišťujte se, že ke všem těmto věcem můžete použít MSVC a Visual Studio.

I když je kód knihovny DLL napsaný v jazyce C++, používáme pro exportované funkce rozhraní ve stylu jazyka C. Existují dva hlavní důvody: Zaprvé, mnoho dalších jazyků podporuje import funkcí ve stylu jazyka C. Klientská aplikace nemusí být napsaná v jazyce C++. Za druhé, zabraňuje některým běžným nástrahám souvisejícím s exportovanými třídami a členskými funkcemi. Při exportu tříd je snadné udělat chyby obtížně diagnostikovatelné, protože vše, na co se v deklaraci třídy odkazuje, musí mít instanci, která je také exportovaná. Toto omezení platí pro knihovny DLL, ale ne statické knihovny. Pokud jsou vaše třídy ve stylu P.O.D. (plain-old-data), neměli byste narazit na tento problém.

Odkazy na další informace o knihovnách DLL naleznete v tématu Vytváření knihoven DLL C/C++ v sadě Visual Studio. Další informace o implicitním propojení a explicitním propojení naleznete v tématu Určení, kterou metodu propojení použít. Informace o vytváření knihoven DLL jazyka C++ pro použití s programovacími jazyky, které používají konvence propojení jazyka C, naleznete v tématu Export funkcí jazyka C++ pro použití ve spustitelných souborech jazyka C. Informace o vytváření knihoven DLL pro použití s jazyky .NET naleznete v tématu Volání funkcí knihovny DLL z aplikací jazyka Visual Basic.

Požadavky

  • Microsoft Windows 7 nebo novější. Pro co nejlepší vývojové prostředí doporučujeme nejnovější verzi Windows.
  • Visual Studio. Informace o tom, jak stáhnout a nainstalovat Visual Studio, najdete v tématu Instalace sady Visual Studio. Při spuštění instalačního programu se ujistěte, že je zaškrtnuta možnost Vývoj desktopových aplikací s C++. Nedělejte si starosti, pokud jste tuto úlohu nenainstalovali při instalaci sady Visual Studio. Instalační program můžete spustit znovu a nainstalovat ho.

    Snímek obrazovky s instalačním programem sady Visual Studio, vývoj desktopových aplikací s pracovní zátěží C++.

  • Visual Studio. Informace o tom, jak stáhnout a nainstalovat Visual Studio 2015, najdete v tématu Instalace sady Visual Studio 2015. K instalaci kompilátoru a nástrojů C++ použijte vlastní instalaci, protože nejsou ve výchozím nastavení nainstalované.

Poznámka:

Tento názorný postup předpokládá, že používáte Visual Studio 2017 verze 15.9 nebo novější. Některé starší verze sady Visual Studio 2017 měly chyby v šablonách kódu nebo používaly různé dialogy uživatelského rozhraní. Chcete-li se vyhnout problémům, použijte instalační program sady Visual Studio k aktualizaci sady Visual Studio 2017 na verzi 15.9 nebo novější.

Vytvořte projekt knihovny DLL

V následující sadě úkolů vytvoříte projekt pro knihovnu DLL, přidáte kód a sestavíte ho. Začněte tím, že spustíte integrované vývojové prostředí sady Visual Studio a pokud potřebujete, přihlaste se. Pokyny se mírně liší podle toho, jakou verzi sady Visual Studio používáte. Pokud chcete zobrazit postup pro upřednostňovanou verzi sady Visual Studio, použijte selektor verzí umístěný v horní části obsahu na této stránce.

Vytvoření projektu knihovny DLL v sadě Visual Studio

  1. Na řádku nabídek zvolte Soubor>nový>projekt a otevřete dialogové okno Vytvořit nový projekt.

    Snímek obrazovky s dialogovým oknem Vytvořit nový projekt se zvýrazněnou šablonou dynamické knihovny

  2. V horní části dialogového okna nastavte jazyk naC++, nastavte platformu pro Windows a nastavte typ projektu na knihovnu.

  3. V seznamu filtrovaných typů projektů vyberte dynamickou knihovnu (DLL) a pak zvolte Další.

  4. Na stránce Konfigurovat nový projekt zadejte do pole Název projektumathLibrary a zadejte název projektu. Ponechte výchozí hodnoty názvu umístění a řešení . Nastavte řešení tak, aby se vytvořilo nové řešení. Zrušte zaškrtnutí políčka Umístit řešení a projekt do stejného adresáře , pokud je zaškrtnuté.

  5. Zvolte tlačítko Vytvořit a vytvořte projekt.

Po vytvoření řešení uvidíte vygenerovaný projekt a zdrojové soubory v okně Průzkumníka řešení v sadě Visual Studio.

Snímek obrazovky s oknem Průzkumníka řešení se zvýrazněným projektem MathLibrary

Vytvoření projektu knihovny DLL v sadě Visual Studio 2017

  1. Na řádku nabídek zvolte >

  2. V levém podokně dialogového okna Nový projekt vyberte Nainstalované>Visual C++>Desktop Windows. V prostředním podokně vyberte Knihovna dynamických odkazů (DLL). Do pole Název zadejte MathLibrary a zadejte název projektu. Ponechte výchozí hodnoty názvu umístění a řešení . Nastavte řešení tak, aby se vytvořilo nové řešení. Zkontrolujte, jestli není zaškrtnuto políčko Vytvořit adresář pro řešení .

    Snímek obrazovky dialogového okna Nový projekt ve Visual Studio 2017, zobrazující 'Math Library' v textovém poli Název.

  3. Výběrem tlačítka OK vytvořte projekt.

Po vytvoření řešení uvidíte vygenerovaný projekt a zdrojové soubory v okně Průzkumníka řešení v sadě Visual Studio.

Snímek obrazovky s oknem Průzkumníka řešení v sadě Visual Studio 2017 se zvýrazněnou knihovnou matematiky

Vytvoření projektu knihovny DLL v sadě Visual Studio 2015 a starších verzích

  1. Na řádku nabídek zvolte Soubor>>

  2. V levém podokně dialogového okna Nový projekt rozbalte nainstalované>šablony a vyberte Visual C++ a pak v prostředním podokně vyberte Konzolová aplikace Win32. Do textového pole Název zadejte MathLibrary a zadejte název projektu. Ponechte výchozí hodnoty názvu umístění a řešení . Nastavte řešení tak, aby se vytvořilo nové řešení. Zkontrolujte, jestli není zaškrtnuto políčko Vytvořit adresář pro řešení .

    Snímek obrazovky s dialogovým oknem Nový projekt v sadě Visual Studio 2015 zobrazující MathLibrary v textovém poli Název

  3. Kliknutím na tlačítko OK zavřete dialogové okno Nový projekt a spustíte Průvodce aplikací Win32.

    Snímek obrazovky Přehled průvodce aplikací Win32

  4. Zvolte tlačítko Další. Na stránce Nastavení aplikace v části Typ aplikace vyberte knihovnu DLL.

    Snímek obrazovky se stránkou Nastavení aplikace Průvodce aplikací Win32

  5. Výběrem tlačítka Dokončit vytvořte projekt.

Po dokončení řešení se v okně Průzkumníka řešení v sadě Visual Studio zobrazí vygenerovaný projekt a zdrojové soubory.

Snímek obrazovky s oknem Průzkumníka řešení v sadě Visual Studio 2015 se zvýrazněnou možností MathLibrary

V tuto chvíli tato knihovna DLL nedělá moc. Dále vytvoříte soubor hlaviček, který deklaruje funkce, které exportujete knihovnou DLL, a pak do knihovny DLL přidáte definice funkcí, aby byla užitečnější.

Přidání hlavičkového souboru do knihovny DLL

  1. Pokud chcete vytvořit soubor záhlaví pro funkce, zvolte na řádku nabídek možnostPřidat novou položku>.

  2. V dialogovém okně Přidat novou položku v levém podokně vyberte Visual C++. V prostředním podokně vyberte Soubor záhlaví (.h). Zadejte MathLibrary.h jako název souboru záhlaví.

    Snímek obrazovky dialogového okna Přidat novou položku, kde je vybrána šablona souboru hlaviček C plus plus a MathLibrary.h je zadané do textového pole Název.

  3. Zvolte tlačítko Přidat a vygenerujte prázdný soubor záhlaví, který se zobrazí v novém okně editoru.

    Snímek obrazovky s prázdným souborem MathLibrary.h v editoru

  4. Obsah souboru záhlaví nahraďte tímto kódem:

    // 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();
    

Tento soubor hlaviček deklaruje některé funkce, které vytvoří generalizovanou fibonacciho sekvenci se dvěma počátečními hodnotami. Volání fibonacci_init(1, 1) vygeneruje známou Fibonacciho číselnou sekvenci.

Všimněte si příkazů preprocesoru v horní části souboru. Nová šablona projektu pro projekt typu DLL přidá <PROJECTNAME>_EXPORTS do definovaných maker preprocesoru. V tomto příkladu Visual Studio definuje MATHLIBRARY_EXPORTS, když je sestaven projekt knihovny DLL pro MathLibrary.

Když je definováno makro MATHLIBRARY_EXPORTS, makro MATHLIBRARY_API nastaví modifikátor __declspec(dllexport) na deklaracích funkcí. Tento modifikátor říká kompilátoru a linkeru, aby exportoval funkci nebo proměnnou z knihovny DLL pro použití jinými aplikacemi. Pokud MATHLIBRARY_EXPORTS je například nedefinovaný, když je soubor hlavičky zahrnutý klientskou aplikací, MATHLIBRARY_API použije __declspec(dllimport) modifikátor na deklarace. Tento modifikátor optimalizuje import funkce nebo proměnné v aplikaci. Další informace naleznete v tématu dllexport, dllimport.

Přidání implementace do knihovny DLL

  1. V Průzkumníku řešení klikněte pravým tlačítkem na uzel Zdrojové soubory a zvolte Přidat>novou položku. Vytvořte nový .cpp soubor s názvem MathLibrary.cppstejným způsobem, jakým jste v předchozím kroku přidali nový hlavičkový soubor.

  2. V okně editoru vyberte kartu MathLibrary.cpp, pokud už je otevřená. Pokud ne, v Průzkumníku řešení poklikejte MathLibrary.cpp do složky Zdrojové soubory projektu MathLibrary a otevřete ho.

  3. V editoru nahraďte obsah MathLibrary.cpp souboru následujícím kódem:

    // 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. V okně editoru vyberte kartu pro MathLibrary.cpp , pokud už je otevřená. Pokud ne, v Průzkumníku řešení poklikejte na MathLibrary.cpp ve složce Zdrojové soubory projektu MathLibrary ho otevřete.

  2. V editoru nahraďte obsah MathLibrary.cpp souboru následujícím kódem:

    // 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_;
    }
    

Chcete-li ověřit, že vše dosud funguje, zkompilujte knihovnu DLL. Chcete-li zkompilovat, zvolte na řádku nabídek Sestavit>Sestavit řešení. Knihovna DLL a související výstup kompilátoru jsou umístěny do složky s názvem Debug přímo pod složkou řešení. Pokud vytvoříte sestavení vydané verze, výstup se umístí do složky s názvem Release. Výstup by měl vypadat nějak takto:

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 ==========

Blahopřejeme, vytvořili jste knihovnu DLL pomocí sady Visual Studio! Dále vytvoříte klientskou aplikaci, která používá funkce exportované knihovnou DLL.

Vytvoření klientské aplikace, která používá knihovnu DLL

Když vytváříte knihovnu DLL, zamyslete se nad tím, jak ji můžou klientské aplikace používat. Aby bylo možné volat funkce nebo přistupovat k datům exportovaným knihovnou DLL, musí zdrojový kód klienta obsahovat deklarace dostupné v době kompilace. Při propojení vyžaduje linker informace k vyřešení volání funkcí nebo přístupu k datům. Knihovna DLL poskytuje tyto informace v knihovně importu, což je soubor, který obsahuje informace o tom, jak najít funkce a data místo skutečného kódu. A v době běhu musí být knihovna DLL k dispozici klientovi v umístění, které může operační systém najít.

Ať už je to vaše vlastní, nebo od jiného výrobce, projekt klientské aplikace potřebuje k použití knihovny DLL několik informací. Potřebuje najít hlavičky, které deklarují export knihovny DLL, knihovny importu pro linker a samotnou knihovnu DLL. Jedním z řešení je zkopírování všech těchto souborů do klientského projektu. U knihoven DLL třetích stran, které se pravděpodobně nezmění, když je váš klient ve vývoji, může být tato metoda nejlepším způsobem, jak je použít. Při sestavování knihovny DLL je ale lepší se vyhnout duplicitám. Pokud vytvoříte místní kopii souborů DLL, které jsou ve vývoji, můžete omylem změnit hlavičkový soubor v jedné kopii, ale ne v druhé nebo použít zastaralé knihovny.

Pokud se chcete vyhnout nesynchronizačnímu kódu, doporučujeme nastavit cestu zahrnutí do projektu klienta tak, aby zahrnovala soubory hlaviček knihovny DLL přímo z projektu knihovny DLL. Také nastavte cestu knihovny ve vašem klientském projektu tak, aby zahrnovala importní knihovny DLL z projektu DLL. Nakonec zkopírujte sestavenou DLL z projektu DLL do výstupního adresáře sestavení klienta. Tento krok umožňuje klientské aplikaci používat stejný kód knihovny DLL, který sestavíte.

Vytvoření klientské aplikace v sadě Visual Studio

  1. Na řádku nabídek zvolte Soubor>nový>projekt a otevřete dialogové okno Vytvořit nový projekt .

  2. V horní části dialogového okna nastavte jazyk na C++, nastavte platformu pro Windows a nastavte typ projektu na konzolu.

  3. V filtrovaném seznamu typů projektů zvolte Konzolová aplikace a pak zvolte Další.

  4. Na stránce Konfigurovat nový projekt zadejte do pole Název projektuMathClient a zadejte název projektu. Ponechte výchozí hodnoty názvu umístění a řešení . Nastavte řešení tak, aby se vytvořilo nové řešení. Zrušte zaškrtnutí políčka Umístit řešení a projekt do stejného adresáře , pokud je zaškrtnuté.

    Snímek obrazovky s dialogovým oknem Vytvořit nový projekt se zvýrazněnou možností Konzolová aplikace

  5. Zvolte tlačítko Vytvořit a vytvořte projekt klienta.

Pro vás je vytvořen minimální projekt konzolové aplikace. Název hlavního zdrojového souboru je stejný jako název projektu, který jste zadali dříve. V tomto příkladu se jmenuje MathClient.cpp. Můžete ji sestavit, ale zatím nepoužívá knihovnu DLL.

Vytvoření klientské aplikace v sadě Visual Studio 2017

  1. Chcete-li vytvořit aplikaci jazyka C++, která používá knihovnu DLL, kterou jste vytvořili, zvolte na řádku nabídek možnost Soubor>nový>projekt.

  2. V levém podokně dialogového okna Nový projekt vyberte Plocha systému Windows pod Nainstalováno>Visual C++. V prostředním podokně vyberte konzolovou aplikaci systému Windows. Do textového pole Název zadejte název projektu MathClient. Ponechte výchozí hodnoty názvu umístění a řešení . Nastavte řešení tak, aby se vytvořilo nové řešení. Zkontrolujte, jestli není zaškrtnuto políčko Vytvořit adresář pro řešení .

    Snímek obrazovky s dialogovým oknem Nový projekt se zvýrazněnou konzolovou aplikací systému Windows a matematickým klientem zadaným do textového pole Název

  3. Zvolte OK a vytvořte projekt klientské aplikace.

Pro vás je vytvořen minimální projekt konzolové aplikace. Název hlavního zdrojového souboru je stejný jako název projektu, který jste zadali dříve. V tomto příkladu se jmenuje MathClient.cpp. Můžete ji sestavit, ale zatím nepoužívá knihovnu DLL.

Vytvoření klientské aplikace v sadě Visual Studio 2015

  1. Chcete-li vytvořit aplikaci jazyka C++, která používá knihovnu DLL, kterou jste vytvořili, zvolte na řádku nabídek možnost Soubor>nový>projekt.

  2. V levém podokně dialogového okna Nový projekt vyberte Win32 v části Nainstalované>šablony>Visual C++. V prostředním podokně vyberte konzolovou aplikaci Win32. Do textového pole Název zadejte název projektu MathClient. Ponechte výchozí hodnoty názvu umístění a řešení . Nastavte řešení tak, aby se vytvořilo nové řešení. Zkontrolujte, jestli není zaškrtnuto políčko Vytvořit adresář pro řešení .

    Snímek obrazovky s dialogovým oknem Nový projekt se zvýrazněnou možností Win32 Console Application Visual C plus plus a Math Client zadaným do textového pole Název.

  3. Kliknutím na tlačítko OK zavřete dialogové okno Nový projekt a spustíte Průvodce aplikací Win32. Na stránce Přehled v dialogovém okně Průvodce aplikací Win32 zvolte tlačítko Další .

  4. Na stránce Nastavení aplikace v části Typ aplikace vyberte Konzolová aplikace , pokud ještě není vybraná.

  5. Výběrem tlačítka Dokončit vytvořte projekt.

Po dokončení průvodce se pro vás vytvoří minimální projekt konzolové aplikace. Název hlavního zdrojového souboru je stejný jako název projektu, který jste zadali dříve. V tomto příkladu se jmenuje MathClient.cpp. Můžete ji sestavit, ale zatím nepoužívá knihovnu DLL.

Pokud chcete volat funkce MathLibrary ve zdrojovém kódu, musí projekt obsahovat MathLibrary.h soubor. Tento soubor hlaviček můžete zkopírovat do projektu klientské aplikace a pak ho přidat do projektu jako existující položku. Tato metoda může být dobrou volbou pro knihovny třetích stran. Pokud ale pracujete na kódu knihovny DLL a klienta najednou, můžou se soubory hlaviček dostat mimo synchronizaci. Chcete-li se tomuto problému vyhnout, nastavte v projektu cestu Další adresáře zahrnutí tak, aby zahrnovala cestu k původní hlavičce.

Přidání hlavičky knihovny DLL do cesty zahrnutí

  1. Kliknutím pravým tlačítkem myši na uzel MathClient v Průzkumníku řešení otevřete dialogové okno Stránky vlastností .

  2. V rozevíracím seznamu Konfigurace vyberte Všechny konfigurace , pokud ještě není vybraná.

  3. V levém podokně vyberte Vlastnosti> konfiguraceC/C++>Obecné.

  4. V podokně vlastností vyberte rozevírací ovládací prvek vedle textového pole Další adresáře zahrnutí a pak zvolte Upravit.

    Snímek dialogového okna Stránky vlastností zobrazující příkaz Upravit v rozevíracím seznamu vlastnosti Další zahrnuté adresáře

  5. Poklikejte v horním podokně dialogového okna Další zahrnutí adresářů a povolte tak ovládací prvek pro úpravy. Nebo zvolte ikonu složky a vytvořte novou položku.

  6. V ovládacím prvku pro úpravy zadejte cestu k umístění MathLibrary.h souboru záhlaví. Můžete zvolit ovládací prvek se třemi tečkami (...) a přejít do správné složky.

    Můžete také zadat relativní cestu ze zdrojových souborů klienta do složky, která obsahuje soubory hlaviček knihovny DLL. Pokud jste postupovali podle pokynů a umístili projekt klienta do řešení odděleného od knihovny DLL, měla by relativní cesta vypadat takto:

    ..\..\MathLibrary\MathLibrary

    Pokud jsou vaše projekty DLL a klienta ve stejném řešení, může relativní cesta vypadat takto:

    ..\MathLibrary

    Pokud jsou knihovny DLL a klientské projekty v jiných složkách, upravte relativní cestu tak, aby odpovídala. Nebo pomocí ovládacího prvku se třemi tečky vyhledejte složku.

    Snímek obrazovky s dialogovým oknem Další adresáře include zobrazující relativní cestu k adresáři MathLibrary

  7. Po zadání cesty k souboru záhlaví v dialogovém okně Další adresáře zahrnout zvolte tlačítko OK . V dialogovém okně Stránky vlastností zvolte tlačítko OK a uložte provedené změny.

Teď můžete soubor zahrnout MathLibrary.h a použít funkce, které deklaruje v klientské aplikaci. Nahraďte obsah MathClient.cpp tímto kódem:

// 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;
}

Tento kód lze zkompilovat, ale ne propojit. Pokud teď sestavíte klientskou aplikaci, zobrazí se v seznamu chyb několik chyb LNK2019. Je to proto, že v projektu chybí některé informace: Zatím jste nezadali, že projekt má závislost na knihovně MathLibrary.lib . A to jste linkerovi neřekli, jak soubor najít MathLibrary.lib .

Pokud chcete tento problém vyřešit, můžete soubor knihovny zkopírovat přímo do projektu klientské aplikace. Linker najde a použije ho automaticky. Pokud se ale knihovna i klientská aplikace vyvíjí, může to vést ke změnám v jedné kopii, která se nezobrazuje v druhé. Chcete-li se tomuto problému vyhnout, můžete nastavit vlastnost Další závislosti tak, aby systém sestavení věděl, že váš projekt závisí na MathLibrary.lib. A můžete nastavit cestu k adresářům další knihovny v projektu tak, aby zahrnovala cestu k původní knihovně při propojení.

Chcete-li přidat knihovnu DLL importu do vašeho projektu

  1. V Průzkumníku řešení klikněte pravým tlačítkem na uzel MathClient a zvolte Vlastnosti a otevřete dialogové okno Stránky vlastností.

  2. V rozevíracím seznamu Konfigurace vyberte Všechny konfigurace , pokud ještě není vybraná. Zajišťuje, že všechny změny vlastností platí pro verze Debug i Release.

  3. V levém podokně vyberte Vlastnosti konfigurace>linker>vstup. V podokně vlastností vyberte rozevírací ovládací prvek vedle textového pole Další závislosti a pak zvolte Upravit.

    Snímek obrazovky zobrazuje dialogové okno Stránky vlastností pod Vstupem, které obsahuje příkaz Upravit v rozevíracím seznamu vlastnosti Další závislosti.

  4. V dialogovém okně Další závislosti přidejte MathLibrary.lib do seznamu v ovládacím prvku pro horní úpravy.

    Snímek obrazovky s dialogovým oknem Další závislosti zobrazující soubor MathLibrary.lib

  5. Kliknutím na tlačítko OK se vrátíte do dialogového okna Stránky vlastností .

  6. V levém panelu vyberte Vlastnosti konfigurace>Linker>Obecné. V podokně vlastností vyberte rozevírací ovládací prvek vedle textového pole Další adresáře knihovny a pak zvolte Upravit.

    Snímek obrazovky dialogového okna Stránky vlastností v sekci Obecné, který zobrazuje příkaz Upravit v rozevíracím seznamu Další adresáře knihovny.

  7. Poklikáním v horním podokně dialogového okna Další adresáře knihovny povolíte ovládací prvek pro úpravy. V ovládacím prvku pro úpravy zadejte cestu k umístění MathLibrary.lib souboru. Ve výchozím nastavení je ve složce Debug přímo ve složce řešení DLL. Pokud vytvoříte sestavení vydané verze, soubor se umístí do složky s názvem Release. Makro můžete použít $(IntDir) , aby linker mohl najít knihovnu DLL bez ohledu na to, jaký druh sestavení vytvoříte. Pokud jste postupovali podle pokynů k umístění projektu klienta do samostatného řešení od projektu knihovny DLL, relativní cesta by měla vypadat takto:

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

    Pokud se vaše projekty DLL a klientské projekty nacházejí v jiných umístěních, upravte relativní cestu tak, aby odpovídala.

    Dialogové okno Další adresáře knihovny – snímek obrazovky

  8. Po zadání cesty k souboru knihovny v dialogovém okně Další adresáře knihovny zvolte tlačítko OK a vraťte se do dialogového okna Stránky vlastností . Chcete-li uložit změny vlastnosti, zvolte OK .

Klientská aplikace se teď může úspěšně zkompilovat a propojit, ale pořád nemá všechno, co potřebuje ke spuštění. Když operační systém načte vaši aplikaci, vyhledá knihovnu DLL pro MathLibrary. Pokud se knihovna DLL nenajde v určitých systémových adresářích, v cestě prostředí nebo v adresáři místní aplikace, načtení se nezdaří. V závislosti na operačním systému se zobrazí chybová zpráva podobná této:

Snímek obrazovky s dialogovým oknem s chybou MathLibrary DLL nebyla nalezena.

Jedním ze způsobů, jak se vyhnout tomuto problému, je zkopírovat knihovnu DLL do adresáře, který obsahuje spustitelný soubor klienta jako součást procesu sestavení. Do projektu můžete přidat událost po sestavení a přidat příkaz, který zkopíruje knihovnu DLL do výstupního adresáře sestavení. Zadaný příkaz zkopíruje knihovnu DLL pouze v případě, že chybí nebo se změnila. Na základě konfigurace sestavení používá makra ke kopírování do a z umístění pro ladění nebo pro verzi k vydání.

Pro zkopírování knihovny DLL v rámci události po sestavení

  1. V Průzkumníku řešení klikněte pravým tlačítkem na uzel MathClient a zvolte Vlastnosti a otevřete dialogové okno Stránky vlastností.

  2. V rozevíracím seznamu Konfigurace vyberte Všechny konfigurace , pokud ještě není vybraná.

  3. V levém podokně vyberte Vlastnosti konfigurace>Události sestavení>Události po sestavení.

  4. V podokně vlastností vyberte ovládací prvek pro úpravy v poli Příkazového řádku . Pokud jste postupovali podle pokynů pro umístění projektu klienta do samostatného řešení od projektu knihovny DLL, zadejte tento příkaz:

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

    Pokud jsou vaše knihovny DLL a klientské projekty v jiných adresářích, změňte relativní cestu ke knihovně DLL tak, aby odpovídala.

    Snímek obrazovky dialogového okna Stránky vlastností zobrazující vlastnost příkazového řádku události po sestavení.

  5. Kliknutím na tlačítko OK uložte změny vlastností projektu.

Teď má vaše klientská aplikace všechno, co potřebuje k sestavení a spuštění. Sestavte aplikaci výběrem možnosti Sestavit>Sestavit řešení na řádku nabídek. Okno Výstup v sadě Visual Studio by mělo mít v závislosti na vaší verzi sady Visual Studio něco jako v následujícím příkladu:

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 ==========

Blahopřejeme, vytvořili jste aplikaci, která volá funkce v knihovně DLL. Teď spusťte aplikaci, abyste viděli, co dělá. Na řádku nabídek zvolte Ladit>Spustit bez ladění. Visual Studio otevře příkazové okno pro spuštění programu. Poslední část výstupu by měla vypadat takto:

Snímek obrazovky s výstupem příkazového okna při spuštění klientské aplikace bez ladění

Stisknutím libovolné klávesy zavřete příkazové okno.

Teď, když jste vytvořili knihovnu DLL a klientskou aplikaci, můžete experimentovat. Zkuste nastavit zarážky v kódu klientské aplikace a spusťte aplikaci v ladicím programu. Podívejte se, co se stane, když vstoupíte do volání knihovny. Přidejte do knihovny další funkce nebo napište jinou klientskou aplikaci, která používá vaši knihovnu DLL.

Když nasadíte aplikaci, musíte také nasadit knihovny DLL, které používá. Nejjednodušší způsob, jak zpřístupnit knihovny DLL, které vytvoříte nebo zahrnujete od třetích stran, je umístit je do stejného adresáře jako vaše aplikace. Označuje se jako místní nasazení aplikace. Další informace o nasazení naleznete v tématu Nasazení v jazyce Microsoft C++.

Viz také