关于动态链接库DLL的入门学习

演练:创建和使用动态链接库 (C++)

由于最近用到DLL,所以赶紧突击学习一下,找到了一些自认为比较好的练手材料,收集整理给后来人,也为了总结下,如下:
先来个网友 写的,热热身,但是请注意——extern "C"问题 ,详情请关注http://blog.csdn.net/lxw907304340/article/details/44922291;
                                                                                                          http://blog.csdn.net/lxw907304340/article/details/44856815;
                                                                                                           http://blog.csdn.net/lxw907304340/article/details/44921855;

下面介绍一下用VS2010如何创建静态链接库和动态链接库,并测试创建的库。

1.静态链接库

打开VS2010,新建一个项目,选择win32项目,点击确定,选择静态库这个选项,预编译头文件可选可不选。

在这个空项目中,添加一个.h文件和一个.cpp文件。名字我们起为static.h和static.cpp

static.h文件:

  1. <span style="font-size: 14px;">#ifndef LIB_H  
  2. #define LIB_H  
  3.   
  4. extern "C" int sum(int a,int b);  
  5.   
  6. #endif</span>  
<span style="font-size: 14px;">#ifndef LIB_H
#define LIB_H

extern "C" int sum(int a,int b);

#endif</span>

static.cpp文件:

  1. <span style="font-size: 14px;">#include "static.h"  
  2.   
  3. int sum(int a,int b)  
  4. {  
  5.     return a+b;  
  6. }</span>  
<span style="font-size: 14px;">#include "static.h"

int sum(int a,int b)
{
	return a+b;
}</span>
编译这个项目之后,会在debug文件夹下生成static.lib文件,这个就是我们需要的静态链接库。


下面说明如何调用静态链接库。

首先需要新建一个空项目,起名为test。将之前static项目下的static.h和static.lib这个2个文件复制到test项目的目录下,并在工程中加入static.h文件。

新建一个test.cpp文件如下:

  1. <span style="font-size: 14px;">#include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include "static.h"  
  4.   
  5. #pragma comment(lib,"static.lib")  
  6.   
  7. int main()  
  8. {  
  9.     printf("%d\n",sum(1,2));  
  10.     system("pause");  
  11.     return 0;  
  12. }</span>  
<span style="font-size: 14px;">#include <stdio.h>
#include <stdlib.h>
#include "static.h"

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

int main()
{
	printf("%d\n",sum(1,2));
	system("pause");
	return 0;
}</span>


编译运行可得结果:3

#pragma comment(lib,"static.lib"),这一句是显式的导入静态链接库。除此之外,还有其他的方法,比如通过设置路径等等,这里不做介绍。


2.动态链接库

和创建静态链接库一样,需要创建一个空的win32项目,选择dll选项。创建dynamic.cpp和dynamic.h文件

dynamic.h文件:

  1. <span style="font-size: 14px;">#ifndef DYNAMIC  
  2. #define DYNAMIC  
  3.   
  4. extern "C" __declspec(dllexport)int sum(int a, int b);  
  5.   
  6. #endif DYNAMIC</span>  
<span style="font-size: 14px;">#ifndef DYNAMIC
#define DYNAMIC

extern "C" __declspec(dllexport)int sum(int a, int b);

#endif DYNAMIC</span>

dynamic.cpp文件:

  1. <span style="font-size: 14px;">#include "dynamic.h"  
  2.   
  3. int sum(int a, int b)  
  4. {  
  5.     return a+b;  
  6. }</span>  
<span style="font-size: 14px;">#include "dynamic.h"

int sum(int a, int b)
{
	return a+b;
}</span>
编译这个项目,会在debug文件夹下生成dynamic.dll文件。

下面介绍如何调用动态链接库,这里讲的是显式的调用。

在刚才的test项目下,把static.lib和static.h文件删除,把dynamic.h和dynamic.dll复制到该目录下,并在项目中添加dynamic.h文件,修改test.cpp文件为:

  1. <span style="font-size: 14px;">#include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include<Windows.h>  
  4. #include "dynamic.h"  
  5. int main()  
  6. {  
  7.     HINSTANCE hDll=NULL;  
  8.     typedef int(*PSUM)(int a,int b);  
  9.     PSUM pSum;  
  10.     hDll = LoadLibrary(L"dynamic.dll");  
  11.     pSum = (PSUM)GetProcAddress(hDll,"sum");  
  12.     printf("%d\n",pSum(1,2));  
  13.     system("pause");  
  14.     FreeLibrary(hDll);  
  15.     return 0;  
  16. }  
  17. </span>  
<span style="font-size: 14px;">#include <stdio.h>
#include <stdlib.h>
#include<Windows.h>
#include "dynamic.h"
int main()
{
	HINSTANCE hDll=NULL;
	typedef int(*PSUM)(int a,int b);
	PSUM pSum;
	hDll = LoadLibrary(L"dynamic.dll");
	pSum = (PSUM)GetProcAddress(hDll,"sum");
	printf("%d\n",pSum(1,2));
	system("pause");
	FreeLibrary(hDll);
	return 0;
}
</span>

编译运行结果为:3

注意:如果从VS2010中直接运行程序,lib和dll需要放到test项目的目录下;如果想双击项目test下的debug文件中的exe文件直接运行的话,需把lib和dll放入debug文件夹下。
此例比较权威,是盖茨家的 :

我们将创建的第一种类型的库是动态链接库 (DLL)。 使用 DLL 是一种重用代码的绝佳方式。 您不必在自己创建的每个程序中重新实现同一例程,而只需对这些例程编写一次,然后从需要该功能的应用程序引用它们即可。

本演练涵盖以下内容:

  • 创建新的动态链接库 (DLL) 项目。

  • 向动态链接库添加类。

  • 创建引用动态链接库的应用程序。

  • 在控制台应用程序中使用类库的功能。

  • 运行应用程序。

本主题假定您具备 C++ 语言的基础知识。 如果您是刚开始学习 C++,建议您参阅 Herb Schildt 编写的“C++ Beginner's Guide”(《C++ 初学者指南》),该书可从http://go.microsoft.com/fwlink/?LinkId=115303 在线获得。

创建新的动态链接库 (DLL) 项目

  1. “文件”菜单中,选择“新建”,然后选择“项目…”

  2. “项目类型”窗格中,选择“Visual C++”下的“Win32”

  3. “模板”窗格中,选择“Win32 控制台应用程序”

  4. 为项目选择一个名称,如 MathFuncsDll,并将其键入“名称”字段。 为解决方案选择一个名称,如 DynamicLibrary,并将其键入“解决方案名称”字段。

  5. 单击“确定”启动 Win32 应用程序向导。 “Win32 应用程序向导”对话框的“概述”页中,单击“下一步”

  6. “Win32 应用程序向导”中的“应用程序设置”页中,选择“应用程序类型”下的“DLL”(如果可用),或者选择“控制台应用程序”(如果“DLL”不可用)。 某些版本的 Visual Studio 不支持通过使用向导创建 DLL 项目。 您可以稍后对此进行更改,以将项目编译为 DLL。

  7. “Win32 应用程序向导”“应用程序设置”页中,选择“附加选项”下的“空项目”

  8. 单击“完成”创建项目。

向动态链接库添加类

  1. 若要为新类创建头文件,请从“项目”菜单中选择“添加新项…” 将显示“添加新项”对话框。 “类别”窗格中,选择“Visual C++”下的“代码” “模板”窗格中选择“头文件(.h)” 为头文件选择一个名称,如 MathFuncsDll.h,并单击“添加” 将显示一个空白文件。

  2. 添加一个名为“MyMathFuncs”的简单类,以执行常见的算术运算,如加、减、乘和除。 代码应与以下内容类似:

    // MathFuncsDll.h
    
    namespace MathFuncs
    {
        class MyMathFuncs
        {
        public:
            // Returns a + b
            static __declspec(dllexport) double Add(double a, double b);
    
            // Returns a - b
            static __declspec(dllexport) double Subtract(double a, double b);
    
            // Returns a * b
            static __declspec(dllexport) double Multiply(double a, double b);
    
            // Returns a / b
            // Throws DivideByZeroException if b is 0
            static __declspec(dllexport) double Divide(double a, double b);
        };
    }
    
  3. 请注意此代码方法声明中的 __declspec(dllexport) 修饰符。 这些修饰符使 DLL 能够导出该方法以供其他应用程序使用。 有关更多信息,请参见 dllexport, dllimport

  4. 若要为新类创建源文件,请从“项目”菜单中选择“添加新项…” 将显示“添加新项”对话框。 “类别”窗格中,选择“Visual C++”下的“代码” “模板”窗格中,选择“C++ 文件(.cpp)” 为源文件选择一个名称,如 MathFuncsDll.cpp,并单击“添加” 将显示一个空白文件。

  5. 在源文件中实现“MyMathFuncs”的功能。 代码应与以下内容类似:

    // MathFuncsDll.cpp
    // compile with: /EHsc /LD
    
    #include "MathFuncsDll.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 new invalid_argument("b cannot be zero!");
            }
    
            return a / b;
        }
    }
    
  6. 若要将项目生成为 DLL,请从“项目”菜单中选择 MathFuncsDll“属性...” 在左窗格中,选择“配置属性”下的“常规” 在右窗格中,将“配置类型”更改为“动态库(.dll)” 单击“确定”保存更改。

    注意注意

    如果您从命令行生成项目,请使用 /LD 编译器选项指定输出文件应为 DLL。 有关更多信息,请参见 /MD、/MT、/LD(使用运行库)

  7. 编译该动态链接库,方法是选择“生成”菜单中的“生成解决方案” 这样就创建了一个可供其他程序使用的 DLL。 有关 DLL 的详细信息,请参见 DLL

创建引用动态链接库的应用程序

  1. 若要创建将引用并使用刚创建的动态链接库的应用程序,请从“文件”菜单中选择“新建”,然后选择“项目...”

  2. “项目类型”窗格中,选择“Visual C++”下的“Win32”

  3. “模板”窗格中,选择“Win32 控制台应用程序”

  4. 为项目选择一个名称(如 MyExecRefsDll),并将其键入“名称”字段。 “解决方案”旁边的下拉列表中选择“添入解决方案” 这会将新项目添加到该动态链接库所属的同一个解决方案中。

  5. 单击“确定”启动“Win32 应用程序向导” “Win32 应用程序向导”对话框的“概述”页中,单击“下一步”

  6. “Win32 应用程序向导”“应用程序设置”页中,选择“应用程序类型”下的“控制台应用程序”

  7. “Win32 应用程序向导”“应用程序设置”页中,清除“附加选项”下的“预编译头”复选框。

  8. “完成”创建项目。

在控制台应用程序中使用类库的功能

  1. 创建新的控制台应用程序后,将为您创建一个空程序。 源文件的名称与您在前面为项目选择的名称相同。 在本示例中,名为“MyExecRefsDll.cpp”。

  2. 若要使用在动态链接库中创建的算术例程,则必须引用该库。 若要执行此操作,请在解决方案资源管理器中选择 MyExecRefsDll 项目,然后从“项目”菜单中选择“引用...” “属性页”对话框中,展开“通用属性”节点,选择“框架和引用”,然后选择“添加新引用...”按钮。 有关“引用...”对话框的更多信息,请参见“<Projectname> 属性页”对话框 ->“通用属性”->“框架和引用”

  3. 显示“添加引用”对话框。 此对话框列出了所有可以引用的库。 “项目”选项卡列出了当前解决方案中的所有项目,以及它们包含的所有库。 “项目”选项卡中,选择 MathFuncsDll。 然后单击“确定”

  4. 若要引用动态链接库的头文件,必须修改包含目录路径。 为此,请在“属性页”对话框中展开“配置属性”节点,然后展开“C/C++”节点,并选择“常规” “附加包含目录”旁边,键入 MathFuncsDll.h 头文件所在位置的路径。

  5. 可执行文件仅在运行时加载动态链接库。 必须告诉系统在哪里查找“MathFuncsDll.dll”。 您可以通过使用 PATH 环境变量做到这一点。 为此,请在“属性页”对话框中展开“配置属性”节点,并选择“调试” “环境”旁边键入以下内容:PATH=<MathFuncsDll.dll 文件的路径>,其中 <MathFuncsDll.dll 文件的路径> 应替换为 MathFuncsDll.dll 的实际位置。 单击“确定”保存所有更改。

    注意注意

    如果要从命令行而不是从 Visual Studio 运行可执行文件,则必须在命令提示符处手动更新 PATH 环境变量,如下所示:set PATH=%PATH%;<MathFuncsDll.dll 文件的路径>,其中 <MathFuncsDll.dll 文件的路径> 应替换为 MathFuncsDll.dll 的实际位置。

  6. 现在,可以在应用程序中使用“MyMathFuncs”类了。 使用以下代码替换“MyExecRefsDll.cpp”的内容:

    // MyExecRefsDll.cpp
    // compile with: /EHsc /link MathFuncsDll.lib
    
    #include <iostream>
    
    #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;
    
        return 0;
    }
    
  7. 通过从“生成”菜单中选择“生成解决方案”,生成可执行文件。

运行应用程序

  1. 确保选择“MyExecRefsDll”作为默认项目。 “解决方案资源管理器”中,选择 MyExecRefsDll,然后选择“项目”菜单中的“设为启动项目”

  2. 若要运行项目,请选择“调试”菜单中的“开始执行(不调试)” 输出应该与下面的内容类似:

    a + b = 106.4
    a - b = -91.6
    a * b = 732.6
    a / b = 0.0747475
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值