Visual Studio 2017 を使用することをお勧めします

チュートリアル: ダイナミック リンク ライブラリの作成と使用 (C++)

 

公開日: 2016年7月

Visual Studio 2017 RC の最新のドキュメントの詳細については、Visual Studio 2017 RC ドキュメントをご参照ください。

このチュートリアルでは、C++ アプリケーションで使用するためのダイナミック リンク ライブラリ (DLL) を作成する方法を説明します。 ライブラリを使用すると、コードを有効に再利用できます。 作成するプログラムごとに同じルーチンを再実装するのではなく、ルーチンを 1 度記述しておき、その機能を必要とするアプリケーションからそれらを参照します。 DLL にコードを記述することによって、それを参照するすべてのアプリケーションの領域を節約できます。またアプリケーションのすべてを再コンパイルすることなく、DLL を更新できます。 DLL の詳細については、「Visual C++ の DLL」を参照してください。

このチュートリアルでは、次の作業について説明します。

  • DLL プロジェクトの作成。

  • DLL へのクラスの追加。

  • DLL を参照するために読み込み時の動的リンクを使用する、コンソール アプリケーションの作成。

  • アプリケーションのクラスから機能の使用。

  • アプリケーションの実行。

このチュートリアルでは、C++ 呼び出し規約を使用するアプリケーションからのみ呼び出すことができる DLL を作成します。 他の言語用の DLL を作成する方法の詳細については、「DLL 関数の Visual Basic アプリケーションからの呼び出し方」を参照してください。

このトピックは、C++ 言語の基本を理解していることを前提としています。

ダイナミック リンク ライブラリ (DLL) プロジェクトを作成するには

  1. メニュー バーで [ファイル][新規][プロジェクト] の順にクリックします。

  2. [新しいプロジェクト] ダイアログ ボックスの左ペインで、[インストールされたテンプレート][Visual C++] を展開し、[Win32] をクリックします。

  3. 中央のペインで [Win32 コンソール アプリケーション] をクリックします。

  4. [名前] ボックスにプロジェクトの名前を入力します。たとえば MathFuncsDll などです。 [ソリューション名] ボックスにソリューションの名前を入力します。たとえば DynamicLibrary などです。 [OK] を選択します。

  5. [Win32 アプリケーション ウィザード] ダイアログ ボックスの [概要] ページで、[次へ] をクリックします。

  6. [アプリケーションの設定] ページの [アプリケーションの種類][DLL] を選択します。

  7. [完了] をクリックすると、プロジェクトが作成されます。

ダイナミック リンク ライブラリにクラスを追加するには

  1. 新しいクラスのヘッダー ファイルを作成するには、メニュー バーで [プロジェクト][新しい項目の追加] の順にクリックします。 [新しい項目の追加] ダイアログ ボックスの左ペインで、[Visual C++] の下で [コード] を選択します。 中央のペインで、[ヘッダー ファイル (.h)] をクリックします。 このヘッダー ファイルの名前を指定します。たとえば、MathFuncsDll.h などとします。[追加] のボタンをクリックします。 空白のヘッダー ファイルが表示されます。

  2. ヘッダー ファイルの最初に次のコードを追加します。

    // MathFuncsDll.h
    
    #ifdef MATHFUNCSDLL_EXPORTS
    #define MATHFUNCSDLL_API __declspec(dllexport) 
    #else
    #define MATHFUNCSDLL_API __declspec(dllimport) 
    #endif
    
    

  3. 加算、減算、乗算、除算などの一般的な数値演算を行うための、MyMathFuncs という名前の基底クラスを追加します。 コードは次のようになります。

    namespace MathFuncs
    {
        // This class is exported from the MathFuncsDll.dll
        class MyMathFuncs
        {
        public: 
            // Returns a + b
            static MATHFUNCSDLL_API double Add(double a, double b); 
    
            // Returns a - b
            static MATHFUNCSDLL_API double Subtract(double a, double b); 
    
            // Returns a * b
            static MATHFUNCSDLL_API double Multiply(double a, double b); 
    
            // Returns a / b
            // Throws const std::invalid_argument& if b is 0
            static MATHFUNCSDLL_API double Divide(double a, double b); 
        };
    }
    

    MATHFUNCSDLL_EXPORTS のシンボルを定義すると、MATHFUNCSDLL_API のシンボルは、このコードのメンバー関数宣言の __declspec(dllexport) 修飾子を設定します。 この修飾子は、関数を DLL でエクスポートして、他のアプリケーションで利用できるようにします。 MATHFUNCSDLL_EXPORTS が未定義の場合に (たとえば、ヘッダー ファイルがアプリケーションに含まれている場合)、MATHFUNCSDLL_API は、メンバー関数宣言の __declspec(dllimport) 修飾子を定義します。 この修飾子によって、アプリケーションへの関数のインポートが最適化されます。 既定では、DLL の新しいプロジェクト テンプレートによって、PROJECTNAME_EXPORTS が DLL プロジェクトの定義済みのシンボルに追加されます。 この例では、MATHFUNCSDLL_EXPORTS は MathFuncsDll プロジェクトのビルド時に定義されます。 詳細については、「dllexport、dllimport」を参照してください。

    System_CAPS_ICON_note.jpg メモ

    コマンド ラインで DLL プロジェクトをビルドする場合、/D のコンパイラ オプションを使用して MATHFUNCSDLL_EXPORTS のシンボルを定義します。

  4. ソリューション エクスプローラー[MathFuncsDll] プロジェクトで、[ソース ファイル] フォルダーにある MathFuncsDll.cpp を開きます。

  5. ソース ファイルに MyMathFuncs の機能を実装します。 コードは次のようになります。

    // MathFuncsDll.cpp : Defines the exported functions for the DLL application.
    //
    
    #include "stdafx.h"
    #include "MathFuncsDll.h"
    #include <stdexcept>
    
    using namespace std;
    
    namespace MathFuncs
    {
        double MyMathFuncs::Add(double a, double b)
        {
            return a + b;
        }
    
        double MyMathFuncs::Subtract(double a, double b)
        {
            return a - b;
        }
    
        double MyMathFuncs::Multiply(double a, double b)
        {
            return a * b;
        }
    
        double MyMathFuncs::Divide(double a, double b)
        {
            if (b == 0)
            {
                throw invalid_argument("b cannot be zero!");
            }
    
            return a / b;
        }
    }
    

  6. メニュー バーで [ビルド][ソリューションのビルド] の順にクリックし、ダイナミック リンク ライブラリをコンパイルします。

    System_CAPS_ICON_note.jpg メモ

    [ビルド] メニューの表示のない Express Edition を使用している場合は、メニュー バーで [ツール][設定][上級者用の設定] を選択してビルド メニューの表示を有効化し、次に [ビルド][ソリューションのビルド] の順に選択します。

    System_CAPS_ICON_note.jpg メモ

    コマンド ラインでプロジェクトをビルドする場合は、/LD コンパイラ オプションを使用して、出力ファイルが DLL になるように指定します。 詳細については、「/MD、/MT、/LD (ランタイム ライブラリの使用)」を参照してください。 C++ の例外処理を有効にするには、/EHsc コンパイラ オプションを使用します。 詳細については、「/EH (例外処理モデル)」を参照してください。

DLL を参照するアプリケーションを作成するには

  1. 作成した DLL を参照して使用する C ++ アプリケーションを作成するには、メニュー バーで [ファイル][新規作成][プロジェクト] の順に選択します。

  2. 左のペインで、[Visual C++] から [Win32] をクリックします。

  3. 中央のペインで [Win32 コンソール アプリケーション] をクリックします。

  4. [名前] ボックスにプロジェクトの名前を入力します。たとえば MyExecRefsDll などです。 [ソリューション] の横のドロップダウン リストで、[ソリューションに追加] をクリックします。 これにより、DLL を含む同じソリューションに新しいプロジェクトを追加します。 [OK] を選択します。

  5. [Win32 アプリケーション ウィザード] ダイアログ ボックスの [概要] ページで、[次へ] をクリックします。

  6. [アプリケーションの設定] ページの [アプリケーションの種類] で、[コンソール アプリケーション] を選択します。

  7. [アプリケーションの設定] ページの [追加のオプション] で、[プリコンパイル済みヘッダー] のチェック ボックスをオフにします。

  8. [完了] をクリックすると、プロジェクトが作成されます。

ダイナミック リンク ライブラリの機能をアプリケーションで使用するには

  1. コンソール アプリケーションを作成すると、空のプログラムが作成されます。 ソース ファイルの名前は、前の処理で付けた名前と同じになります。 この例では、「MyExecRefsDll.cpp」という名前です。

  2. DLL 内に作成された数値演算ルーチンをアプリケーションで使用するには、それを参照する必要があります。 そのためには、ソリューション エクスプローラーで MyExecRefsDll プロジェクトを選択し、メニュー バーで [プロジェクト][参照] の順にクリックします。 [プロパティ ページ] ダイアログ ボックスで、[共通プロパティ] ノードを展開し、[Framework と参照] をクリックします。次に、[新しい参照の追加] ボタンをクリックします。 [参照設定] ダイアログ ボックスの詳細については、「参照の追加」を参照してください。

  3. [参照の追加] ダイアログ ボックスには、参照できるライブラリが表示されます。 [プロジェクト] タブでは、現在のソリューション内のプロジェクト、およびそれらに含まれるすべてのライブラリが表示されます。 [プロジェクト] タブで、MathFuncsDll の横にあるチェック ボックスをオンにし、[OK] ボタンをクリックします。

  4. DLL のヘッダー ファイルを参照するには、含まれるディレクトリ パスを変更する必要があります。 このためには、[プロパティ ページ] ダイアログ ボックスで、[構成プロパティ] ノードを展開し、[C/C++] ノードを展開して、[全般] をクリックします。 [追加のインクルード ディレクトリ] の横に、MathFuncsDll.h ヘッダー ファイルへのパスを指定します。 相対パスを使用できます。たとえば、..\MathFuncsDll\ として、[OK] のボタンをクリックします。

  5. これで、MyMathFuncs クラスをこのアプリケーションで使用できます。 MyExecRefsDll.cpp の内容を次のコードに置き換えます。

    // MyExecRefsDll.cpp
    // compile with: /EHsc /link MathFuncsDll.lib
    
    #include <iostream>
    
    #include "MathFuncsDll.h"
    
    using namespace std;
    
    int main()
    {
        double a = 7.4;
        int b = 99;
    
        cout << "a + b = " <<
            MathFuncs::MyMathFuncs::Add(a, b) << endl;
        cout << "a - b = " <<
            MathFuncs::MyMathFuncs::Subtract(a, b) << endl;
        cout << "a * b = " <<
            MathFuncs::MyMathFuncs::Multiply(a, b) << endl;
        cout << "a / b = " <<
            MathFuncs::MyMathFuncs::Divide(a, b) << endl;
    
        try
        {
            cout << "a / 0 = " <<
                MathFuncs::MyMathFuncs::Divide(a, 0) << endl; 
        }
        catch (const invalid_argument &e) 
        {
            cout << "Caught exception: " << e.what() << endl; 
        }
    
        return 0;
    }
    

  6. メニュー バーで [ビルド][ソリューションのビルド] の順にクリックして、実行可能ファイルをビルドします。

アプリケーションを実行するには

  1. MyExecRefsDll が既定のプロジェクトとして選択されていることを確認します。 ソリューション エクスプローラーで [MyExecRefsDll] を選択し、メニュー バーで [プロジェクト][スタートアップ プロジェクトに設定] の順にクリックします。

  2. プロジェクトを実行するには、メニュー バーで [デバッグ][デバッグなしで開始] の順にクリックします。 出力は、次のようになります。

a + b = 106.4
a - b = -91.6
a * b = 732.6
a / b = 0.0747475
例外がキャッチされました: b を 0 にすることはできません。

Visual C++ Guided Tour
Visual C++ の DLL
デスクトップ アプリケーションの配置
チュートリアル: プログラムの配置 (C++)
DLL 関数の Visual Basic アプリケーションからの呼び出し方

表示: