天天看點

動态連結庫

1動态連結庫的制作

我們先來示範如何使用VS2015建立一個動态連結庫。

1.建立一個“Win32控制台應用程式”,“名稱”為MathFuncsDll,“解決方案名稱”為DynamicLibrary,單擊“确定”。

動态連結庫

2.單擊“下一步”,“應用程式類型”選擇“DLL”,“附加選項”勾選“空項目”,單擊“完成”。

動态連結庫

3.為解決方案“DynamicLibrary”下的項目“MathFuncsDll”添加頭檔案MathFuncsDll.h,代碼如下:

動态連結庫
//testdll.h
#ifdef TESTDLL_EXPORTS  
#define TESTDLL_API __declspec(dllexport)   
#else  
#define TESTDLL_API __declspec(dllimport)   
#endif  
namespace MathFuncs  
{  
    // This class is exported from the testdll.dll  
    class MyMathFuncs  
    {  
    public:   
        // Returns a + b  
        static TESTDLL_API double Add(double a, double b);

        // Returns a - b  
        static TESTDLL_API double Subtract(double a, double b);

        // Returns a * b  
        static TESTDLL_API double Multiply(double a, double b);

        // Returns a / b  
        // Throws const std::invalid_argument& if b is 0  
        static TESTDLL_API double Divide(double a, double b);
    };  
}
      

  

// testdll.cpp : 定義 DLL 應用程式的導出函數。
#include "stdafx.h"
#include "testdll.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;  
    }  
}
      

編譯就會生成對應的dll檔案,同時也會生成對應的lib檔案  

2動态連結庫的調用

2.1隐式連結

采用靜态加載的方式,比較簡單,需要.h、.lib、.dll三件套。建立“控制台應用程式”或“空項目”。配置如下: 

項目->屬性->配置屬性->VC++ 目錄-> 在“包含目錄”裡添加頭檔案testdll.h所在的目錄 

項目->屬性->配置屬性->VC++ 目錄-> 在“庫目錄”裡添加頭檔案testdll.lib所在的目錄 

項目->屬性->配置屬性->連結器->輸入-> 在“附加依賴項”裡添加“testdll.lib”(若有多個 lib 則以空格隔開) 

現在可以編譯通過了,但是程式運作就報錯,還需要将testdll.dll複制到目前項目生成的可執行檔案所在的目錄。 

//mydll.cpp
#include <iostream>  
#include "testdll.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;  
}
      

2.2顯式連結

是應用程式在執行過程中随時可以加載DLL檔案,也可以随時解除安裝DLL檔案,這是隐式連結所無法作到的,是以顯式連結具有更好的靈活性,對于解釋性語言更為合适。 

建立項目,不需要特殊配置,添加cpp檔案

/*
 *作者:侯凱
 *說明:顯式調用DLL
 *日期:2013-6-5
*/
#include<Windows.h> //加載的頭檔案
#include<iostream>
using namespace std;

int main()  
{  
    typedef double (*pAdd)(double a, double b);
    typedef double (*pSubtract)(double a, double b);
 
    HMODULE hDLL = LoadLibrary("testdll.dll"); //加載dll檔案 
    if(hDLL != NULL)  
    {  
        pAdd fp1 = pAdd(GetProcAddress(hDLL, MAKEINTRESOURCE(1))); //得到dll中的第一個函數
        if(fp1 != NULL)  
        {   
            cout<<fp1(2.5, 5.5)<<endl; 
        }  
        else  
        {  
            cout<<"Cannot Find Function "<<"add"<<endl;  
        }  
        pSubtract fp2 = pSubtract(GetProcAddress(hDLL, "?Subtract@MyMathFuncs@MathFuncs@@SANNN@Z")); //得到dll中标示為"?..."的函數,C++編譯器考慮了函數的參數
        if(fp2 != NULL)  
        {  
            cout<<fp2(5.5, 2.5)<<endl;  
        }  
        else  
        {  
            cout<<"Cannot Find Function "<<"Subtract"<<endl;  
        }  
        FreeLibrary(hDLL);  
    }  
    else  
    {  
        std::cout<<"Cannot Find "<<"testdll"<<std::endl;  
    }  
    return 1;  
}
      
上一篇: linux基礎
下一篇: Linux 基礎