Dll的编写:
现在新建的Dll工程中创建一个新的类,我在这个类中简单定义了Add, Substract, Mutiply, Divide这4个方法
具体代码如下:(MathFuncs.h)
#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
注意要在类地外部将所要使用的方法用前面定义的关键字进行导出。
然后再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文件。
显示调用,又称动态调用,具体思路为:
定义相应的函数指针 -> 使用LoadLibrary加载需要使用的dll -> 利用GetProcAddress方法根据dll中的方法名称调用相应的方法 -> 使用FreeLibrary释放调用的dll文件
代码如下:
//在显式调用中,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; }
接下来是隐式调用:
先要把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; }