Dll的編寫與Dll的顯示調用和隱式調用

Dll的編寫:
ios

    如今新建的Dll工程中建立一個新的類,我在這個類中簡單定義了Add, Substract, Mutiply, Divide這4個方法
c++

    具體代碼以下:(MathFuncs.h)
windows

#pragma once

#ifndef _MathFuncs_H
#define _MathFuncs_H

//定義函數導出
#ifdef __cplusplus
#define MyDll extern "C" __declspec(dllexport)  
#else
#define  MyDll __declspec(dllexport)
#endif // __cplusplus

//若不使用extern "C"關鍵字,則C++編譯器會打亂函數的名稱,使利用函數名的顯式調用這種調用方式失敗
//加上這個關鍵字是爲了保持函數名的完整性
//#define MyDll  __declspec(dllexport)  

MyDll double Add(double a, double b);
MyDll double Substract(double a, double b);
MyDll double Mutiply(double a, double b);
MyDll double Divide(double a, double b);

class MathFuncs
{
public:
    MathFuncs(void);
    ~MathFuncs(void);

    double Add(double a, double b);

    double Substract(double a, double b);

    double Mutiply(double a, double b);

    double Divide(double a, double b);
};

#endif // !_MathFuncs_H

    注意要在類地外部將所要使用的方法用前面定義的關鍵字進行導出。
ide

    而後再cpp文件中實現他們,代碼以下:
函數

#include "stdafx.h"
#include "MathFuncs.h"
#include <stdexcept>

using namespace std;

MathFuncs::MathFuncs(void)
{
}

MathFuncs::~MathFuncs(void)
{
}

double MathFuncs::Add(double a, double b)
{
    return a + b;
}

double MathFuncs::Substract(double a, double b)
{
    return a - b;
}

double MathFuncs::Mutiply(double a, double b)
{
    return a * b;
}

double MathFuncs::Divide(double a, double b)
{
    if (0 == b)
    {
	  throw new invalid_argument("b can not be zero!");
    } 
    else
    {
	  return a / b;
    }
}

//輸出的方法都要將包含方法的類實例化
//輸出的方法的實體不能含有類名
double Add(double a, double b)
{
    MathFuncs clsMF;
    return clsMF.Add(a, b);
}

double Substract(double a, double b)
{
    MathFuncs clsMF;
    return clsMF.Substract(a, b);
}

double Mutiply(double a, double b)
{
    MathFuncs clsMF;
    return clsMF.Mutiply(a, b);
}

double Divide(double a, double b)
{
    MathFuncs clsMF;
    return clsMF.Divide(a, b);
}

    完成後,將工程編譯一下能夠獲得dll、lib等文件。如今咱們來使用這個dll文件。
spa

    顯示調用,又稱動態調用,具體思路爲:
指針

    定義相應的函數指針 -> 使用LoadLibrary加載須要使用的dll -> 利用GetProcAddress方法根據dll中的方法名稱調用相應的方法 -> 使用FreeLibrary釋放調用的dll文件
code

    代碼以下:
ip

//在顯式調用中,c++和c調用動態庫的寫法是同樣的

//顯示調用(動態調用)
//1. 定義相應的函數指針
//2.使用LoadLibrary加載須要使用到的Dll
//3. 利用Dll中方法的名稱調用裏面的方法
//4. 使用FreeLibrary釋放加載的Dll文件

#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <conio.h>  //控制檯輸出、輸入,其中包含了經過控制檯進行數據輸入和數據輸出的函數
#include <string>

//動態調用函數所使用的函數指針必定要與所調用Dll中方法的返回值和參數徹底一致
typedef double (*Calculate)(double a, double b);

using namespace std;

int main(void)
{
    HINSTANCE hDll;  //新建一個用於儲存所調用Dll的句柄

    //注意寬字符版要用TEXT()去更改輸入字符
    hDll = LoadLibrary(TEXT("../UsingDll/MathFuncsDll.dll"));  //「..」表示當前程序的「exe」文件所在路徑的父路徑(上一級路徑)

    if (NULL != hDll)
    {
	  double a, b, dblResult;
	  string strSign;

	  cout << "請輸入所要使用的計算方法(Add, Substract, Mutiply, Divide):";
	  getline(cin, strSign);
	  LPCSTR lpcStr = strSign.c_str();  //string轉LPCSTR

	  cout << "請輸入元素a:";
	  cin >> a;
	  cout << endl << "請輸入元素b:";
	  cin >> b;
	 
	  Calculate pCalculate = NULL;  //定義一個函數指針

	  pCalculate = (Calculate)GetProcAddress(hDll, lpcStr);  //獲取Dll中名爲「lpcStr」的方法

	  if (NULL != pCalculate)
	  {
		dblResult = (*pCalculate)(a, b);
		cout << "調用Dll中方法計算後的結果爲:" << dblResult << endl;

		FreeLibrary(hDll);  //在動態調用完Dll後必須使用該方法將其釋放
	  }
	  else
	  {
		cout << "調用Dll中方法失敗!" << endl;
	  }
    }

    system("pause");
    return 0;
}

    接下來是隱式調用:
ci

    先要把dll工程中生成的lib文件導入到本工程,而後把dll文件放在程序運行的根目錄下(.exe)或者system32文件夾中,跟着利用代碼把要使用到的方法用關鍵字__declspec(dllimport)將他們導入。

    代碼以下:

#include <iostream>

//隱式調用
//在導入Dll中方法時要在extern後使用"C"來防止C++編譯器改變方法的名稱
//1. 要先導入要用到的Dll中的方法(名稱、參數等徹底一致)
//2. 而後將對應的lib文件添加進工程
//3. 所使用的Dll文件必定要和exe文件處於同一路徑之下,或者system32文件夾中
extern "C" __declspec(dllimport)double Add(double a, double b);
extern "C" __declspec(dllimport)double Substract(double a, double b);
extern "C" __declspec(dllimport)double Mutiply(double a, double b);
extern "C" __declspec(dllimport)double Divide(double a, double b);

using namespace std;

int main(_In_ int _Argc, char* argv[] )
{
    double a, b;
    double dblAddResult, dblSubstractResult, dblMutiplyResult, dblDivideResult;

    cout << "請輸入a:";
    cin >> a;
    cout << endl << "請輸入b:";
    cin >> b;

    dblAddResult = Add(a, b);

    dblSubstractResult = Substract(a, b);

    dblMutiplyResult = Mutiply(a, b);

    dblDivideResult = Divide(a, b);

    cout << "利用Dll中Add方法獲得的結果爲:" << dblAddResult << endl;
    cout << "利用Dll中Substract方法獲得的結果爲:" << dblSubstractResult << endl;
    cout << "利用Dll中Mutiply方法獲得的結果爲:" << dblMutiplyResult << endl;
    cout << "利用Dll中Divide方法獲得的結果爲:" << dblDivideResult << endl;

    system("pause");

    return 0;
}
相關文章
相關標籤/搜索