程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> c++ 創建和使用動態鏈接庫 DLL

c++ 創建和使用動態鏈接庫 DLL

編輯:關於C++

動態鏈接庫DLL文件是c++學習中很重要的一點。DLL文件有很多的有點,可以被一個程序甚至多個程序調用,節省了內存,共享了資源。DLL庫不同於靜態庫,在靜態庫情況下,函數和數據被編譯進一個二進制文件(通常擴展名為*.LIB), Visual C++的編譯器在處理程序代碼時將從靜態庫中恢復這些函數和數據並把他們和應用程序中的其他模塊組合在一起生成可執行文件。這個過程稱為"靜態鏈接",此時因為應用程序所需的全部內容都是從庫中復制了出來,所以靜態庫本身並不需要與可執行文件一起發行。

  在動態庫的情況下,有兩個文件,一個是引入庫(.LIB)文件,一個是DLL文件,引入庫文件包含被DLL導出的函數的名稱和位置,DLL包含實際的函數和數據,應用程序使用LIB文件鏈接到所需要使用的DLL文件,庫中的函數和數據並不復制到可執行文件中,因此在應用程序的可執行文件中,存放的不是被調用的函數代碼,而是DLL中所要調用的函數的內存地址,這樣當一個或多個應用程序運行是再把程序代碼和被調用的函數代碼鏈接起來,從而節省了內存資源。從上面的說明可以看出,DLL和.LIB文件必須隨應用程序一起發行,否則應用程序將會產生錯誤。
 

創建動態鏈接庫 (DLL) 項目

在菜單欄上,依次選擇“文件”“新建”“項目”

“新建項目”對話框的左窗格中,依次展開“已安裝”“模板”“Visual C++”,然後選擇“Win32”

在中間窗格中,選擇“Win32 控制台應用程序”

“名稱”框中為項目指定名稱,例如 MathFuncsDll。在“解決方案名稱”框中為解決方案指定名稱,例如 DynamicLibrary。選擇“確定”按鈕。

“Win32 應用程序向導”對話框的“概述”頁上,選擇“下一步”按鈕。

“應用程序設置”頁面的“應用程序類型”下,選擇“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); 
    };
}

在此代碼中,當 MATHFUNCSDLL_EXPORTS 符號已經被定義時,成員函數聲明部分的 MATHFUNCSDLL_API 符號將被設置為 __declspec(dllexport) 修飾符。此修飾符使函數能作為 DLL 導出,以供其他應用程序調用。如果未定義 MATHFUNCSDLL_EXPORTS(例如,應用程序包含了頭文件),則 MATHFUNCSDLL_API 將定義成員函數聲明中的 __declspec(dllimport) 修飾符。此修飾符將優化在應用程序中導入該函數的操作。默認情況下,DLL 的“新建項目”模板會將 PROJECTNAME_EXPORTS 添加到 DLL 項目的已定義符號中。在本例中,生成 MathFuncsDll 項目後將定義 MATHFUNCSDLL_EXPORTS。有關詳細信息,請參閱aspx" target="_blank">dllexport、dllimport。

System_CAPS_note注意

如果你要在命令行上生成 DLL 項目,請使用 /D 編譯器選項來定義 MATHFUNCSDLL_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;
    }
}

通過選擇菜單欄中的 生成>生成解決方案 編譯動態鏈接庫

System_CAPS_note注意

如果使用的是不顯示“生成”菜單的 Express 版,請在菜單欄上,依次選擇“工具”“設置”“專家設置”來啟用它,然後依次選擇“生成”“生成解決方案”

System_CAPS_note注意

如果在命令行中生成項目,請使用 /LD 編譯器選項指定輸出文件為 DLL。有關詳細信息,請參閱/MD、/MT、/LD(使用運行庫)。使用 /EHsc 編譯器選項啟用 C++ 異常處理。有關詳細信息,請參閱/EH(異常處理模型)。

創建引用 DLL 的應用

為了創建一個項目引用你剛剛創建好的DLL,在菜單欄中選擇 文件>新建>項目。

在左窗格中的“Visual C++”下,選擇“Win32”

在中間窗格中,選擇“Win32 控制台應用程序”

“名稱”框中為項目指定名稱,例如 MyExecRefsDll。在“解決方案”旁邊,從下拉列表中選擇“添加到解決方案”。這會將新項目添加到包含此 DLL 的同一解決方案中。選擇“確定”按鈕。

“Win32 應用程序向導”對話框的“概述”頁上,選擇“下一步”按鈕。

“應用程序設置”頁的“應用程序類型”下,選擇“控制台應用程序”

“應用程序設置”頁的“附加選項”下,清除“預編譯頭”復選框。

選擇“完成”按鈕創建項目。

在該應用中使用類庫中的功能

在創建一個控制台應用程序後,一個空的程序已經為你創建好了。源文件的名稱與你之前選擇的名稱相同。在此示例中,其名稱為 MyExecRefsDll.cpp。

若要在應用中使用在 DLL 中創建的數學例程,必須對它進行引用。為此,請在 解決方案資源管理器 中選擇 MyExecRefsDll 項目,然後在菜單欄上,選擇 項目,引用。在“屬性頁”對話框中,展開“通用屬性”節點、選擇“框架和引用”,然後選擇“添加新引用”按鈕。有關“引用”對話框的更多信息,請參見在 Visual C++ 項目中添加引用。

“添加引用”對話框列出了可以引用的庫。“項目”選項卡列出了當前解決方案中的所有項目以及它們包含的所有庫。在“項目”選項卡上,選中“MathFuncsDll”旁邊的復選框,然後選擇“確定”按鈕。

若要引用 DLL 的頭文件,必須修改包含的目錄路徑。若要執行此操作,請在“屬性頁”對話框中,依次展開“配置屬性”節點和“C/C++”節點,然後選擇“常規”。在“附加包含目錄”旁邊,指定 MathFuncsDll.h 頭文件的位置路徑。你可以使用相對路徑(例如 ..\MathFuncsDll\),然後選擇“確定”按鈕。

現在即可在此應用程序中使用 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;
}

通過在菜單欄上依次選擇“生成”“生成解決方案”來生成可執行文件。

運行應用程序

請確保已將 MyExecRefsDll 選為默認項目。在“解決方案資源管理器”中,選擇 MyExecRefsDll,然後在菜單欄上,依次選擇“項目”“設為啟動項目”

若要運行項目,請在菜單欄上依次選擇“調試”“開始執行(不調試)”。輸出應該與下面的內容類似:

a + b = 106.4
a - b = -91.6
a * b = 732.6
a / b = 0.0747475
捕獲到異常:b 不能為零!

同上,也可以在類名前添加 MATHFUNCSDLL_API 使類作為DLL導出。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved