DLL编程 — C++基础dll类库

DLL ,就是将函数提供给EXE使用。

避免所有的代码都放在EXE中

32  64 位系统  dll 基本放在这两个文件夹下:
C:\Windows\System32
C:\Windows\SysWOW64

1.Dll工程

创建一个 类库 工程,取名为 ClassLibrary 如下图示:

 

 

工程默认文件如下:




我们再添加一个cpp 比如:test.cpp,并像平常一样写几个函数如下:

  

 

然后生成 (不能运行的! 它和exe虽然是同等级dll文件是无法独立运行)

在生成目录中,我们能看到生成了一个 ClassLibrary.dll 文件,这个是我们最终想要的

 
 

 

我们将生成的dll拖入depends.exe 中,发现右侧无任何内容。 这其实也是正确的。



dll本来就是一个供他人使用的一个链接库,既然供它人使用,那么,我们就应该将函数以接口的形式提供给他人。

像平常的函数一样,它是无法跨文件被使用的。

那么,我们现在应该怎么做呢?

 

 

在每个函数名前加上: _declspec(dllexport) 

这名话的作用是将函数定义为导出函数,也就是说这个函数要被包含这个函数的程序之外的程序调用

#include "Stdafx.h"

 

_declspec(dllexport)  int add(int aint b)

{

return a + b;

}

 

_declspec(dllexport)  int add(int aint bint c)

{

return a + b + c;

}

 

_declspec(dllexport)  int sub(int aint b)

{

return a – b;

}

 

然后再看一下生成目录: 多了一个.lib文件,此文件叫引入库文件,这个lib是要将函数提供给第三方开发使用的。里面就有我们的导出函数

 

 

 

我们再次将dll拖入depends.exe中,

 

 

 

 

会发现多了三个东西,即我们导出的三个函数,

在此处,函数名和我们写的函数名完全变了,其实就是发生了名字改编(名字粉碎),这也是C++实现重载的核心。两个add函数的重载,表现都为两个不一样名字的函数了。

 

 

 

这样就实现了我们的函数导出

 

接下来,我们就来使用此生成的DLL文件

 



2. 主程序使用

再新建一个Win32控制台空项目,比如touserdll

然后添加如下代码:

 

#include <stdio.h>

#include <Windows.h>

#pragma comment(lib"ClassLibrary.lib")

 

extern int add(int aint b); // 会向外寻找这个函数   到lib中找add函数

int main()

{

int nRes = add(9, 3);

printf("%d  \n"nRes);

system("pause");

return 0;

}

 

因为我们用到dll文件中的函数,所以要把dll生成的lib放至我们的源目录下面(和当前的main函数文件处在同一个文件夹),然后将lib用预处理指令导入进来

因为add函数是在外面定义的,所以我们要用extern声明一下它不是在我们的当前文件下实现的。

如果没有lib,它会在链接的时候就会失败

如(LINK : fatal error LNK1104: 无法打开文件“d:\..qzher..ojects\touserdll\Debug\touserdll.exe”


最后,生成一个exe文件,运行的时候,会提示找不到dll文件。

 

原因:exe文件运行的时候要使用到dll文件的add函数,然而,在此时并没有dll文件,所以报错了。我们需要将dll工程生成的.dll文件复制到我们的exe运行目录中,和exe同级,exe在运行的时候就会自动找到此dll

 

 

 

 

我们也可以将生成的exe拖入depends中,发现它的DLL依赖库中就有ClassLibrary.dll

 

 

DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。一个应用程序可使用多个DLL文件,一个DLL文件也可能被不同的应用程序使用,这样的DLL文件被称为共享DLL文件。

动态链接具有下列优点:

  • 节省内存和减少交换操作。很多进程可以同时使用一个 DLL,在内存中共享该 DLL 的一个副本。相反,对于每个用静态链接库生成的应用程序,Windows 必须在内存中加载库代码的一个副本。

  • 节省磁盘空间。许多应用程序可在磁盘上共享 DLL 的一个副本。相反,每个用静态链接库生成的应用程序均具有作为单独的副本链接到其可执行图像中的库代码。

  • 升级到 DLL 更为容易。当 DLL 中的函数发生更改时,只要函数的参数和返回值没有更改,就不需重新编译或重新链接使用它们的应用程序。相反,静态链接的对象代码要求在函数更改时重新链接应用程序。

  • 提供售后支持。例如,可修改显示器驱动程序 DLL 以支持当初交付应用程序时不可用的显示器。

  • 支持多语言程序。只要程序遵循函数的调用约定,用不同编程语言编写的程序就可以调用相同的 DLL 函数。程序与 DLL 函数在下列方面必须是兼容的:函数期望其参数被推送到堆栈上的顺序,是函数还是应用程序负责清理堆栈,以及寄存器中是否传递了任何参数。

  • 提供了扩展 MFC 库类的机制。可以从现有 MFC 类派生类,并将它们放到 MFC 扩展 DLL 中供 MFC 应用程序使用。

  • 使国际版本的创建轻松完成。通过将资源放到 DLL 中,创建应用程序的国际版本变得容易得多。可将用于应用程序的每个语言版本的字符串放到单独的 DLL 资源文件中,并使不同的语言版本加载合适的资源。

发表评论

电子邮件地址不会被公开。 必填项已用*标注