dll文件详解.docx

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

dll文件详解.docx

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

dll文件详解.docx

dll文件详解

dll文件详解

DLL文件详解

Part1

dll文件与exe文件的区别:

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

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

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

具体说:

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

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

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

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

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

它的内部可以用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