c++ダイナミックリンクライブラリDLLの作成と使用

9993 ワード

ダイナミックリンクライブラリDLLファイルはc++学習において重要な点である.DLLファイルには多くの点があり、1つのプログラムから複数のプログラムに呼び出され、メモリを節約し、リソースを共有することができます.DLLライブラリは静的ライブラリとは異なり、静的ライブラリの場合、関数とデータはバイナリファイル(通常は*.LIB拡張子)にコンパイルされ、Visual C++のコンパイラはプログラムコードを処理する際に静的ライブラリからこれらの関数とデータを復元し、アプリケーション内の他のモジュールと組み合わせて実行可能ファイルを生成します.このプロシージャを「静的リンク」と呼びます.この場合、アプリケーションに必要なすべてのコンテンツがライブラリからコピーされるため、静的ライブラリ自体が実行可能ファイルとともに発行される必要はありません.ダイナミックライブラリの場合、2つのファイルがあります.1つは導入ライブラリ(.LIB)ファイルです.1つはDLLファイルです.導入ライブラリファイルにはDLLによってエクスポートされた関数の名前と場所が含まれています.DLLには実際の関数とデータが含まれています.アプリケーションはLIBファイルを使用して必要なDLLファイルにリンクします.ライブラリ内の関数とデータは実行可能ファイルにコピーされません.したがって、アプリケーションの実行可能ファイルには、呼び出された関数コードではなく、DLLで呼び出される関数のメモリアドレスが格納され、1つ以上のアプリケーションが実行されると、プログラムコードと呼び出された関数コードがリンクされ、メモリリソースが節約される.以上の説明から分かるように、DLLと.LIBファイルはアプリケーションとともに発行する必要があります.そうしないと、アプリケーションにエラーが発生します.次の内容はhttps://msdn.microsoft.com/zh-cn/library/ms235636.aspx
ダイナミックリンクライブラリ(DLL)プロジェクトの作成
メニューバーで、[ファイル](File)、[新規](New)、[プロジェクト](Projects)の順に選択します.

「新規プロジェクト」ダイアログ・ボックスの左ペインで、「インストール済」、「テンプレート」、「Visual C++」の順に展開し、「Win 32」を選択します.

中間ペインで、「Win 32コンソールアプリケーション」を選択します.

「名前」ボックスで、MathFuncsDllなどのプロジェクトの名前を指定します.「ソリューション名」ボックスで、DynamicLibraryなどのソリューションの名前を指定します.「OK」ボタンを選択します.

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

[アプリケーション設定]ページの[アプリケーションタイプ]で、[DLL]を選択します.

「完了」ボタンを選択してプロジェクトを作成します.

ダイナミックリンクライブラリへのクラスの追加
新しいクラスのヘッダファイルを作成するには、メニューバーで「プロジェクト」、「新規アイテムの追加」の順に選択します.[新しいアイテムを追加]ダイアログボックスの左ペインで、[Visual C++]で[コード]を選択します.中間ペインで、「ヘッダーファイル(.h)」を選択します.ヘッダーファイルの名前(MathFuncsLib.hなど)を指定し、「追加」ボタンを選択します.空白のヘッダファイルが表示されます.

ヘッダー・ファイルの先頭に次のコードを追加します.
C++
コピー
// MathFuncsDll.h

#ifdef MATHFUNCSDLL_EXPORTS
#define MATHFUNCSDLL_API __declspec(dllexport) 
#else
#define MATHFUNCSDLL_API __declspec(dllimport) 
#endif



MyMathFuncsというベースクラスを追加して、一般的な算術演算(加算、減算、乗算、除算など)を実行します.コードは次のようになります.
C++
コピー
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); 
    };
}

このコードでは、MATHFUNSDLL_EXPORTSシンボルが定義されている場合、メンバー関数宣言部のMATHFUNSDLL_APIシンボルが__に設定されますdeclspec(dllexport)修飾子.この修飾子は、関数をDLLとしてエクスポートして、他のアプリケーションで呼び出すことができます.MATHFUNCSDLL_が定義されていない場合EXPORTS(例えば、アプリケーションにヘッダファイルが含まれている)ではMATHFUNSDLL_APIは、メンバー関数宣言の__を定義します.declspec(dllimport)修飾子.この修飾子は、アプリケーションに関数をインポートする操作を最適化します.デフォルトでは、DLLの「新規プロジェクト」テンプレートはPROJECTNAME_EXPORTSはDLLプロジェクトの定義済みシンボルに追加されます.この例では、MathFuncsDllプロジェクトを生成するとMATHFUNSDLL_が定義されます.EXPORTS.詳細については、dllexport、dllimportを参照してください.
に注意
コマンドラインでDLLアイテムを生成する場合は、/Dコンパイラオプションを使用してMATHFUNSDLL_を定義します.EXPORTS記号.

ソリューションエクスプローラの「MathFuncsDll」プロジェクトで、「ソースファイル」フォルダでMathFuncsDllを開きます.cpp.

ソースファイルのMyMathFuncs機能を実現します.コードは次のようになります.
C++
コピー
// MathFuncsDll.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "MathFuncsDll.h"
#include 

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


メニューバーの「構築」>「ソリューションの生成」を選択してダイナミックリンクライブラリをコンパイル
に注意
「生成」メニューが表示されないExpress版を使用している場合は、メニューバーで「ツール」、「設定」、「エキスパート設定」の順に選択して有効にし、「生成」、「ソリューションの生成」の順に選択します.
に注意
コマンドラインでアイテムを生成する場合は、/LDコンパイラオプションを使用して出力ファイルをDLLに指定します.詳細については、/MD、/MT、/LD(ライブラリの使用)を参照してください./EHscコンパイラオプションを使用して、C++例外処理を有効にします.詳細については、/EH(例外処理モデル)を参照してください.

DLLを参照するアプリケーションの作成
作成したDLLを参照するプロジェクトを作成するには、メニューバーで「ファイル」>「新規」>「プロジェクト」を選択します.

左ペインの「Visual C++」で、「Win 32」を選択します.

中間ペインで、「Win 32コンソールアプリケーション」を選択します.

「名前」ボックスで、MyExecRefsDllなどのプロジェクトの名前を指定します.「ソリューション」の横で、ドロップダウン・リストから「ソリューションに追加」を選択します.これにより、このDLLを含む同じソリューションに新しいプロジェクトが追加されます.「OK」ボタンを選択します.

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

≪アプリケーション設定|Application Settings|ldap≫ページの「≪アプリケーション・タイプ|Application Type|ldap≫」で、「≪コンソール・アプリケーション|Console Application|ldap≫」を選択します.

≪アプリケーション設定|Application Settings|ldap≫ページの「≪追加オプション|Additional Options|ldap≫」で、「≪プリコンパイル・ヘッダ|Pre-Compute Header|ldap≫」チェック・ボックスをオフにします.

「完了」ボタンを選択してプロジェクトを作成します.

このアプリケーションでクラスライブラリの機能を使用する
コンソールアプリケーションを作成すると、空のプログラムが作成されます.ソースファイルの名前は、前に選択した名前と同じです.この例では、MyExecRefsDllという名前である.cpp.

DLLで作成した数学ルーチンをアプリケーションで使用するには、参照する必要があります.そのためには、ソリューションエクスプローラでMyExecRefsDllプロジェクトを選択し、メニューバーでプロジェクトを選択し、参照してください.「プロパティ・ページ」ダイアログ・ボックスで、「汎用プロパティ」ノードを展開し、「フレームと参照」を選択し、「新規参照の追加」ボタンを選択します.[参照]ダイアログボックスの詳細については、Visual C++プロジェクトに参照を追加するを参照してください.

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

DLLのヘッダファイルを参照するには、含まれるディレクトリパスを変更する必要があります.この操作を行うには、[プロパティ・ページ]ダイアログ・ボックスで[プロパティの構成]ノードと[C/C+]ノードを展開し、[一般]を選択します.「追加含むディレクトリ」の横に、MathFuncsDllを指定します.hヘッダファイルの位置パス.相対パス(..MathFuncsDll)など)を使用して、「OK」ボタンを選択します.

このアプリケーションでMyMathFuncsクラスを使用できるようになりました.MyExecRefsDll.cppの内容は次のコードに置き換えられます.
C++
コピー
// MyExecRefsDll.cpp
// compile with: /EHsc /link MathFuncsDll.lib

#include 

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


メニューバーで[生成](Generate)、[ソリューションを生成](Generate Resolution)の順に選択して実行可能ファイルを生成します.

アプリケーションの実行
MyExecRefsDllがデフォルトアイテムとして選択されていることを確認してください.ソリューションエクスプローラでMyExecRefsDllを選択し、メニューバーで「プロジェクト」、「開始プロジェクトとして設定」の順に選択します.

プロジェクトを実行するには、メニューバーで「デバッグ」、「実行開始(デバッグなし)」の順に選択します.出力は次のようになります.
a + b = 106.4
a - b = -91.6
a * b = 732.6
a / b = 0.0747475
     :b     !


同様に、クラス名の前にMATHFUNSDLL_を追加することもできますAPIはクラスをDLLとしてエクスポートする.