dll文件详解.docx

上传人:b****8 文档编号:10404930 上传时间:2023-02-11 格式:DOCX 页数:11 大小:54.08KB
下载 相关 举报
dll文件详解.docx_第1页
第1页 / 共11页
dll文件详解.docx_第2页
第2页 / 共11页
dll文件详解.docx_第3页
第3页 / 共11页
dll文件详解.docx_第4页
第4页 / 共11页
dll文件详解.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

dll文件详解.docx

《dll文件详解.docx》由会员分享,可在线阅读,更多相关《dll文件详解.docx(11页珍藏版)》请在冰豆网上搜索。

dll文件详解.docx

dll文件详解

dll文件详解

DLL文件详解

Part1

dll文件与exe文件的区别:

动态链接库(DynamicLinkLibrary,缩写为DLL)

是一个可以被其它应用程序共享的程序模块,其中封装了一些可以被共享的例程和资源。

动态链接库文件的扩展名一般是dll,也有可能是drv、sys和fon,它和可执行文件(exe)非常类似.

具体说:

DLL中虽然包含了可执行代码却不能单独执行,而应由Windows应用程序直接或间接调用。

动态链接是相对于静态链接而言的。

所谓静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分。

换句话说,函数和过程的代码就在程序的exe文件中,该文件包含了运行时所需的全部代码。

当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源。

2.MFC常规DLL是适用MFC创建的,就像MFC程序跟Win32程序的关系一样,MFC常规DLL和Win32DLL的关系也是如此。

它使用MFC的机制,只能导出标准C函数。

如此,它便可以被大部分Win32程序调用。

3.MFC拓展DLL也也使用的是MFC机制创建的,相比于MFC常规DLL,拓展DLL可以导出C++类和MFC派生类,如此扩大了DLL的接口范围。

此长彼消,MFC拓展DLL的适用范围较小,只能被MFC程序调用。

因为它导出的不只是函数,还有C++类和MFC派生类。

三者区别展开来说:

MFCDLL和win32DLL的差别就是一个使用MFC类库,一个不使用,如果你代码中用到的MFC,那么一定要创建MFCDLL,因为win32DLL用不了MFC类。

MFC常规DLL在DLL内部可以用MFC类的,但是给外部的接口并不提供MFC类的支持,还是提供Win32DLL同样的接口,与Win32的差别在于,它的内部可以用MFC类。

扩展DLL可以有C++的接口,它可以导出C++类给客户端。

导出的函数可以使用C++/MFC数据类型做参数或返回值,导出一个类时客户端能创建类对象或者派生这个类。

同时,在DLL中也可以使用MFC。

MFC扩展DLL是通常实现从现有Microsoft基础类库类派生的可重用类的DLL。

MFC扩展DLL具有下列功能和要求:

1客户端可执行文件必须是用定义的_AFXDLL编译的MFC应用程序。

2扩展DLL也可由动态链接到MFC的规则DLL使用。

3扩展DLL应该用定义的_AFXEXT编译。

这将强制同时定义_AFXDLL,并确保从MFC头文件中拉入正确的声明。

它也确保了在生成DLL时将AFX_EXT_CLASS定义为__declspec(dllexport),这在使用此宏声明扩展DLL中的类时是必要的。

4扩展DLL不应实例化从CWinApp派生的类,而应依赖客户端应用程序(或DLL)提供此对象。

5但扩展DLL应提供DllMain函数,并在那里执行任何必需的初始化。

扩展DLL是使用MFC动态链接库版本(也称作共享MFC版本)生成的。

只有用共享MFC版本生成的MFC可执行文件

(应用程序或规则DLL)才能使用扩展DLL。

客户端应用程序和扩展DLL必须使用相同版本的MFCx0.dll。

使用扩展DLL,可以从MFC派生新的自定义类,然后将此“扩展”版本的MFC提供给调用DLL的应用程序。

具体执行时,主要是资源的管理:

mfc扩展dll会把当前dll的句柄加入一个全局资源句柄列表。

而普通的dll则不会。

即使支持mfc也不会,这样你每次用mfc类创建资源的时候要多写几行代码。

但你用在mfc扩展dll用win32来访问资源也需要多写代码。

==============================================================

扩展DLL可以导出类

扩展DLL服务器方的类定义:

classAFX_CLASS_EXPORT到出类名:

public基类名

{

............

}

扩展DLL客户方的类声明头文件:

#pragmacomment(lib,"lib文件名")

classAFX_CLASS_IMPORT到出类名:

public基类名

{

............

}

==============================================================

常规DLL可以导出标准C语言函数

常规DLL服务器方的函数定义:

//

头文件中函数声明

extern"C"__declspec(dllexport)

返回值函数名

形式参数声明

//源文件中函数实现

extern"C"__declspec(dllexport)

返回值函数名

形式参数声明

AFX_MANAGE_STATE(AfxGetStaticModuleState());//

第一条语句

..............

 

//

在def模块文件中声明函数序号

EXPORTS导出函数名@序号数字

常规DLL客户方的隐式函数声明头文件:

======================================================

另外,所有的动态链接库都有两种链接方式:

隐式调用和显示调用。

隐式调用

编译程序时需要头文件、lib文件,运行时需要DLL文件,并且运行过程中DLL文件一直被占用。

显式调用

编译时什么都不需要,在需要使用DLL中的函数时,通过LoadLibrary()和FindProcAdress()这两个API调用。

只需要一个DLL文件即可,而且在需要使用的时候DLL才被占用,使用完毕即被解除占用。

DLL中有哪些函数可以通过Depends工具查询。

==================================================================

Part2

如何制作生成dll文件?

一.Win32动态链接库

  1.制作的步骤:

  

(1)新建WIN32Dynamic-linkLibrary工程,工程名为MyDll,选择AsimpleDLLproject类型。

  

(2)MyDll.h的内容如下:

以下是引用片段:

  extern"C"_declspec(dllexport)intsum(inta,intb);//本文所有的例子只有一个sum即加法函数。

  (3)MyDll.cpp的内容如下:

以下是引用片段:

  #include"stdafx.h"

  #include"windows.h"

  #include"MyDll.h"

  BOOLAPIENTRYDllMain(

  HANDLEhModule,

  DWORDul_reason_for_call,

  LPVOIDlpReserved

  )

  {

  returnTRUE;

  }

  extern"C"_declspec(dllexport)intsum(inta,intb)

  {

  returna+b;

  }

  (4)编译之后产生了MyDll.lib与MyDll.dll两个文件。

 

  2.使用方法:

  

(1).隐式调用法:

将MyDll.lib和MyDll.h拷贝到需要应用该DLL的工程的目录下,将MyDll.dll拷贝到产生的应用程序的目录下,并在需要应用该DLL中的函数的CPP文件中添加如下几行:

以下是引用片段:

  #include"MyDll.h"

  #pragmacomment(lib,"MyDll");

  

(2).显示调用法:

将MyDll.lib和MyDll.h拷贝到需要应用该DLL的工程的目录下,将MyDll.dll拷贝到产生的应用程序的目录下,并在需要应用该DLL中的函数的CPP文件中包含头文件,如:

以下是引用片段:

  #include"MyDll.h"

  同时还需要在Project->Setting->Link->Object/librarymodules的框中增加MyDll.lib这个库。

二.MFC动态链接库

  1.制作的步骤:

  

(1)新建MFCAppWizard(dll)工程,工程名为MFCDll,选择RegularDLLusingsharedMFCDLL类型。

  

(2)在生成的MFCDll.cpp文件后面增加下面几行:

以下是引用片段:

  intsum(inta,intb)

  {

  returna+b;

  }

  (3)在生成的MFCDll.def文件后面增加如下:

以下是引用片段:

  sum@1;表示第一个函数是sum

  (4)编译后会产生两个文件MFCDll.lib,MFCDll.dll

  2.使用方法

  

(1)隐式调用法:

将MFCDll.lib拷贝到需要应用该DLL的工程的目录下,将MyDll.dll拷贝到产生的应用程序的目录下,并在需要应用该DLL中的函数的CPP文件中添加如下几行:

  //注意这里没有在MFCDll.h中声明函数,所以不能直接包含MFCDll.h来声明函数。

以下是引用片段:

  #pragmacomment(lib,"MFCDll");

  intsum(inta,intb);

  //当然如果你的DLL中有很多函数,那可以另外写个MFCDll.h,包含所有的函数声明,然后直接将头文件包含进去

  

(2)显示调用法:

与Win32的调用方法一样,不需要#pragmacomment(lib,"MFCDll");,但是需要在Project->Setting->Link->Object/librarymodules的框中增加MFCDll.lib这个库。

==========================================================

另一个例子:

具体在写DLL文件头文件中一般如此:

#ifdefDLL_EXPORT

#defineDECLDIR__declspec(dllexport)

#else

#defineDECLDIR__declspec(dllimport)

#endif

extern"C"

{

DECLDIRvoidalert();

}

这样使得在定义了DLL_EXPORT的环境下,头文件中,函数为导出;相反为导入。

于是,我们可以使用同一个头文件。

此时是在写DLL,还是在使用DLL,只需要通过这个开关来告诉编译器就可以了。

 

实现cpp中一般这么写:

#include"stdafx.h"

 

#defineDLL_EXPORT

#include"MyHead.h"

extern"C"

{

DECLDIRvoidalert()

{

MessageBoxA(NULL,"Hello,World!

",0,0);

}

}

在引用头文件前定义DLL_EXPORT,告诉编译器此时这些函数需要导出。

隐式调用

#include"stdafx.h"

#include"MyHead.h"

#pragmacomment(lib,"MyTestDLL.lib")

int_tmain(intargc,_TCHAR*argv[])

{

alert();//直接调用

return0;

}

由于我们没有定义DLL_EXPORT,那么头文件中的函数就会被从DLL中导入。

 

显式调用

 

#include"stdafx.h"

#include

typedefvoid(*alert)();

int_tmain(intargc,_TCHAR*argv[])

{

alertfunc=NULL;

HINSTANCEh=LoadLibraryA("MyTestDLL.dll");

if(h)

func=(alert)GetProcAddress(h,"alert");

if(NULL!

=func)

func();

FreeLibrary(h);

return0;

}

首先定义函数指针类型,然后实例化一个该类型的函数。

最后调用即可。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 文学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1