DLL模块:C++在VS下创建、调用dll

1.dll的优点

代码复用是提高软件开发效率的重要途径。一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用。比较常见的例子是各种应用程序框架,ATL、MFC等,它们都以源代码的形式发布。由于这种复用是“源码级别”的,源代码完全暴露给了程序员,因而称之为“白盒复用”。“白盒复用”的缺点比较多,总结起来有4点。

暴露了源代码;多份拷贝,造成存储浪费;

容易与程序员的“普通”代码发生命名冲突;

更新功能模块比较困难,不利于问题的模块化实现;

实际上,以上4点概括起来就是“暴露的源代码”造成“代码严重耦合”。为了弥补这些不足,就提出了“二进制级别”的代码复用。使用二进制级别的代码复用一定程度上隐藏了源代码,对于缓解代码耦合现象起到了一定的作用。这样的复用被称为“黑盒复用”。

说明:实现“黑盒复用”的途径不只dll一种,静态链接库甚至更高级的COM组件都是。

2.dll的创建

我在原文基础上做了一点修改,把那个类给去掉了。。

参考程序原文:http://msdn.microsoft.com/zh-cn/library/ms235636.aspx

新建“Win32项目”,选择应用程序类型为"DLL”,其他默认。

添加头文件testdll.h

 1 //testdll.h
 2 #ifdef TESTDLL_EXPORTS  
 3 #define TESTDLL_API __declspec(dllexport)   //这个修饰符使得函数能都被DLL输出,所以他能被其他应用函数调用
 4 #else  
 5 #define TESTDLL_API __declspec(dllimport)   //这个修饰符使得编译器优化DLL中的函数接口以便于被其他应用程序调用
 6 #endif  
 7 namespace MathFuncs  
 8 {  
 9     // This class is exported from the testdll.dll  
10     // Returns a + b  
11     extern TESTDLL_API double Add(double a, double b);
12 
13     // Returns a - b  
14     extern TESTDLL_API double Subtract(double a, double b);
15 
16     // Returns a * b  
17     extern TESTDLL_API double Multiply(double a, double b);
18 
19     // Returns a / b  
20     // Throws const std::invalid_argument& if b is 0  
21     extern TESTDLL_API double Divide(double a, double b);
22 }

添加cpp文件

 1 // testdll.cpp : 定义 DLL 应用程序的导出函数。
 2 #include "stdafx.h"
 3 #include "testdll.h"  
 4 #include <stdexcept>  
 5 using namespace std;  
 6 
 7 namespace MathFuncs  
 8 {  
 9     double Add(double a, double b)  
10     {  
11         return a + b;  
12     }  
13 
14     double Subtract(double a, double b)  
15     {  
16         return a - b;  
17     }  
18 
19     double Multiply(double a, double b)  
20     {  
21         return a * b;  
22     }  
23 
24     double Divide(double a, double b)  
25     {  
26         if (b == 0)  
27         {  
28             throw invalid_argument("b cannot be zero!");  
29         }  
30         return a / b;  
31     }  
32 }

编译就会生成对应的dll文件,同时也会生成对应的lib文件。

以下为调用的步骤:

在DLL工程中能找到相应工程名的.h .lib .dll

然后把这三个文件添加到需要调用他的工程的文件夹里面,在编译的代码前面加上预处理语句

#pragma comment(lib,"testdll.lib")

然后包涵头文件#include "testdll.h"

以下给出一个demo:

 1 //demo.cpp
 2 #include <iostream>  
 3 #include "testdll.h"
 4 #pragma comment(lib,"testdll.lib")
 5 using namespace std;  
 6 
 7 int main()  
 8 {  
 9     double a = 7.4;  
10     int b = 99;  
11 
12     cout << "a + b = " <<  
13         MathFuncs::Add(a, b) << endl;  
14     cout << "a - b = " <<  
15         MathFuncs::Subtract(a, b) << endl;  
16     cout << "a * b = " <<  
17         MathFuncs::Multiply(a, b) << endl;  
18     cout << "a / b = " <<  
19         MathFuncs::Divide(a, b) << endl;  
20     return 0;  
21 }