`

动态链接库的创建

    博客分类:
  • VC++
 
阅读更多

摘自:http://www.360doc.com/content/14/0727/20/13826502_397488293.shtml

在这个链接的上下篇中还有其他的VC++的相关知识。可以系统的学习一下。

 

三、动态链接库的创建

  在Visual C++6.0开发环境下,打开FileNewProject选项,可以选择Win32 Dynamic-Link Library或MFC AppWizard[dll]来以不同的方式来创建Non-MFC Dll、Regular Dll、Extension Dll等不同种类的动态链接库。

  1. Win32 Dynamic-Link Library方式创建Non-MFC DLL动态链接库

  每一个DLL必须有一个入口点,这就象我们用C编写的应用程序一样,必须有一个WINMAIN函数一样。在Non-MFC DLL中DllMain是一个缺省的入口函数,你不需要编写自己的DLL入口函数,用这个缺省的入口函数就能使动态链接库被调用时得到正确的初始化。如果应用程序的DLL需要分配额外的内存或资源时,或者说需要对每个进程或线程初始化和清除操作时,需要在相应的DLL工程的.CPP文件中对DllMain()函数按照下面的格式书写。
 

 

BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
.......
case DLL_THREAD_ATTACH:
.......
case DLL_THREAD_DETACH:
.......
case DLL_PROCESS_DETACH:
.......
}
return TRUE;
}
 

  参数中,hMoudle是动态库被调用时所传递来的一个指向自己的句柄(实际上,它是指向_DGROUP段的一个选择符);ul_reason_for_call是一个说明动态库被调原因的标志,当进程或线程装入或卸载动态链接库的时候,操作系统调用入口函数,并说明动态链接库被调用的原因,它所有的可能值为:DLL_PROCESS_ATTACH: 进程被调用、DLL_THREAD_ATTACH: 线程被调用、DLL_PROCESS_DETACH: 进程被停止、DLL_THREAD_DETACH: 线程被停止;lpReserved为保留参数。到此为止,DLL的入口函数已经写了,剩下部分的实现也不难,你可以在DLL工程中加入你所想要输出的函数或变量了。

  我们已经知道DLL是包含若干个函数的库文件,应用程序使用DLL中的函数之前,应该先导出这些函数,以便供给应用程序使用。要导出这些函数有两种方法,一是在定义函数时使用导出关键字_declspec(dllexport),另外一种方法是在创建DLL文件时使用模块定义文件.Def。需要读者注意的是在使用第一种方法的时候,不能使用DEF文件。下面通过两个例子来说明如何使用这两种方法创建DLL文件。

  1)使用导出函数关键字_declspec(dllexport)创建MyDll.dll,该动态链接库中有两个函数,分别用来实现得到两个数的最大和最小数。在MyDll.h和MyDLL.cpp文件中分别输入如下原代码:
 

//MyDLL.h
extern "C" _declspec(dllexport) int Max(int a, int b);
extern "C" _declspec(dllexport) int Min(int a, int b);
//MyDll.cpp
#include
#include"MyDll.h"
int Max(int a, int b)
{
if(a>=b)return a;
else
return b;
}
int Min(int a, int b)
{
if(a>=b)return b;
else
return a;
}
 

  该动态链接库编译成功后,打开MyDll工程中的debug目录,可以看到MyDll.dll、MyDll.lib两个文件。LIB文件中包含DLL文件名和DLL文件中的函数名等,该LIB文件只是对应该DLL文件的"映像文件",与DLL文件中,LIB文件的长度要小的多,在进行隐式链接DLL时要用到它。读者可能已经注意到在MyDll.h中有关键字"extern C",它可以使其他编程语言访问你编写的DLL中的函数。

  2)用.def文件创建工程MyDll

  为了用.def文件创建DLL,请先删除上个例子创建的工程中的MyDll.h文件,保留MyDll.cpp并在该文件头删除#include MyDll.h语句,同时往该工程中加入一个文本文件,命名为MyDll.def,再在该文件中加入如下代码:

LIBRARY MyDll
EXPORTS
Max
Min

  其中LIBRARY语句说明该def文件是属于相应DLL的,EXPORTS语句下列出要导出的函数名称。我们可以在.def文件中的导出函数后加@n,如Max@1,Min@2,表示要导出的函数顺序号,在进行显式连时可以用到它。该DLL编译成功后,打开工程中的Debug目录,同样也会看到MyDll.dll和MyDll.lib文件。

  2.MFC AppWizard[dll]方式生成常规/扩展DLL

  在MFC AppWizard[dll]下生成DLL文件又有三种方式,在创建DLL是,要根据实际情况选择创建DLL的方式。一种是常规DLL静态链接到MFC,另一种是常规DLL动态链接到MFC。两者的区别是:前者使用的是MFC的静态链接库,生成的DLL文件长度大,一般不使用这种方式,后者使用MFC的动态链接库,生成的DLL文件长度小;动态链接到MFC的规则DLL所有输出的函数应该以如下语句开始: 
 

AFX_MANAGE_STATE(AfxGetStaticModuleState( )) //此语句用来正确地切换MFC模块状态
 

  最后一种是MFC扩展DLL,这种DLL特点是用来建立MFC的派生类,Dll只被用MFC类库所编写的应用程序所调用。前面我们已经介绍过,Extension DLLs 和Regular DLLs不一样,它没有一个从CWinApp继承而来的类的对象,编译器默认了一个DLL入口函数DLLMain()作为对DLL的初始化,你可以在此函数中实现初始化,代码如下:
 

BOOL WINAPI APIENTRY DLLMain(HINSTANCE hinstDll,DWORD reason ,LPVOID flmpload)
{
switch(reason)
{
……………//初始化代码;
}
return true;
}
 

  参数hinstDll存放DLL的句柄,参数reason指明调用函数的原因,lpReserved是一个被系统所保留的参数。对于隐式链接是一个非零值,对于显式链接值是零。

  在MFC下建立DLL文件,会自动生成def文件框架,其它与建立传统的Non-MFC DLL没有什么区别,只要在相应的头文件写入关键字_declspec(dllexport)函数类型和函数名等,或在生成的def文件中EXPORTS下输入函数名就可以了。需要注意的是在向其它开发人员分发MFC扩展DLL 时,不要忘记提供描述DLL中类的头文件以及相应的.LIB文件和DLL本身,此后开发人员就能充分利用你开发的扩展DLL了。

四、动态链接库DLL的链接

  应用程序使用DLL可以采用两种方式:一种是隐式链接,另一种是显式链接。在使用DLL之前首先要知道DLL中函数的结构信息。Visual C++6.0在VCin目录下提供了一个名为Dumpbin.exe的小程序,用它可以查看DLL文件中的函数结构。另外,Windows系统将遵循下面的搜索顺序来定位DLL: 1.包含EXE文件的目录,2.进程的当前工作目录, 3.Windows系统目录, 4.Windows目录,5.列在Path环境变量中的一系列目录。

  1.隐式链接

  隐式链接就是在程序开始执行时就将DLL文件加载到应用程序当中。实现隐式链接很容易,只要将导入函数关键字_declspec(dllimport)函数名等写到应用程序相应的头文件中就可以了。下面的例子通过隐式链接调用MyDll.dll库中的Min函数。首先生成一个项目为TestDll,在DllTest.h、DllTest.cpp文件中分别输入如下代码:
 

 

//Dlltest.h
#pragma comment(lib,"MyDll.lib")
extern "C"_declspec(dllimport) int Max(int a,int b);
extern "C"_declspec(dllimport) int Min(int a,int b);
//TestDll.cpp
#include
#include"Dlltest.h"
void main()
{int a;
a=min(8,10)
printf("比较的结果为%d ",a);
}
 
 

  在创建DllTest.exe文件之前,要先将MyDll.dll和MyDll.lib拷贝到当前工程所在的目录下面,也可以拷贝到windows的System目录下。如果DLL使用的是def文件,要删除TestDll.h文件中关键字extern "C"。TestDll.h文件中的关键字Progam commit是要Visual C+的编译器在link时,链接到MyDll.lib文件,当然,开发人员也可以不使用#pragma comment(lib,"MyDll.lib")语句,而直接在工程的Setting->Link页的Object/Moduls栏填入MyDll.lib既可。

  2.显式链接

  显式链接是应用程序在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件,这是隐式链接所无法作到的,所以显式链接具有更好的灵活性,对于解释性语言更为合适。不过实现显式链接要麻烦一些。在应用程序中用LoadLibrary或MFC提供的AfxLoadLibrary显式的将自己所做的动态链接库调进来,动态链接库的文件名即是上述两个函数的参数,此后再用GetProcAddress()获取想要引入的函数。自此,你就可以象使用如同在应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或MFC提供的AfxFreeLibrary释放动态链接库。下面是通过显式链接调用DLL中的Max函数的例子。
 

#include 
#include
void main(void)
{
typedef int(*pMax)(int a,int b);
typedef int(*pMin)(int a,int b);
HINSTANCE hDLL;
PMax Max
HDLL=LoadLibrary("MyDll.dll");//加载动态链接库MyDll.dll文件;
Max=(pMax)GetProcAddress(hDLL,"Max");
A=Max(5,8);
Printf("比较的结果为%d ",a);
FreeLibrary(hDLL);//卸载MyDll.dll文件;
}
 

  在上例中使用类型定义关键字typedef,定义指向和DLL中相同的函数原型指针,然后通过LoadLibray()将DLL加载到当前的应用程序中并返回当前DLL文件的句柄,然后通过GetProcAddress()函数获取导入到应用程序中的函数指针,函数调用完毕后,使用FreeLibrary()卸载DLL文件。在编译程序之前,首先要将DLL文件拷贝到工程所在的目录或Windows系统目录下。

  使用显式链接应用程序编译时不需要使用相应的Lib文件。另外,使用GetProcAddress()函数时,可以利用MAKEINTRESOURCE()函数直接使用DLL中函数出现的顺序号,如将GetProcAddress(hDLL,"Min")改为GetProcAddress(hDLL, MAKEINTRESOURCE(2))(函数Min()在DLL中的顺序号是2),这样调用DLL中的函数速度很快,但是要记住函数的使用序号,否则会发生错误。

分享到:
评论

相关推荐

    C# dll的调用(动态链接库创建与使用)

    本文将深入探讨C#中如何创建、使用DLL以及动态链接库的工作原理。 首先,我们要理解什么是DLL。DLL本质上是一些预先编译好的函数和类的集合,它们以库的形式存储,可以在运行时被多个程序加载。这不仅减少了磁盘...

    Linux静态and动态链接库 创建和使用

    ### Linux静态和动态链接库创建和使用 #### 概述 在软件开发过程中,经常会遇到相同功能模块在多个项目中重复出现的情况。例如,多个项目可能都需要实现用户验证功能。为了避免代码重复,提高代码的可维护性和重用...

    动态链接库的建立与调用

    ### 动态链接库的建立与调用 #### 实验目的 本实验旨在帮助学习者深入理解动态链接库(Dynamic Link Library,简称DLL)的工作原理及其在Windows环境下的具体实现方式。通过动手实践,学生将能够熟悉DLL的创建流程...

    VC 动态链接库创建和调用全过程详解.pdf

    VC 动态链接库创建和调用全过程详解 本文将详细介绍 VC 动态链接库(DLL)的概念、分类、创建和调用过程,以及与静态链接库的区别。 一、动态链接库(DLL)的概念 DLL 是一种仓库,提供给开发者一些可以直接拿来...

    系统程序设计:动态链接库程序设计

    1.创建一个动态链接库,在该动态链接库中添加一个函数,该函数可以输出如图所示的图形; 2.在上面创建的动态链接库中添加导出类,并把绘制图形的函数添加到该类下; 3.创建一个动态链接库,在该动态链接库中添加一个...

    静态、动态链接库的创建和调用

    创建动态链接库也类似,需要新建一个Win32控制台应用程序并选择创建DLL。在代码中,所有需要被外部调用的函数前需要加上导出声明(如使用Visual C++的 __declspec(dllexport))。编译后,会得到一个.dll文件和相应的...

    VC++动态链接库创建和调用全过程详解(word文档良心出品).doc

    【VC++动态链接库创建和调用全过程详解】 动态链接库(DLL,Dynamic Linkable Library)是Windows操作系统中的一种共享代码的方式,它允许程序在运行时动态加载和卸载库中的函数和数据,从而实现代码的共享和优化。...

    Qt如何使用lib库封装界面一(Qt5动态链接库创建和使用)

    本教程将详细介绍如何在Qt5环境下创建和使用动态链接库。动态链接库(.dll文件)允许我们把功能模块化,降低代码的耦合度,同时减少应用程序的体积,因为多个程序可以共享同一个库。 首先,我们需要创建一个动态...

    linux动态链接库的开发实例

    3. 创建动态链接库:使用`gcc`或`g++`的 `-shared` 参数,结合`-o`指定输出文件名,将对象文件转换为动态链接库,例如: ``` gcc -shared -o libmylib.so libfunc.o ``` 三、使用动态链接库 1. 链接阶段:在编译...

    实验五 动态链接库的建立与调用

    首先,需要创建一个新的动态链接库项目,然后编写源代码,最后编译和链接生成动态链接库文件。 例如,下面是一个简单的动态链接库的源代码: ```c extern "C" _declspec(dllexport) int Add(int x,int y); extern ...

    VC++动态链接库创建和调用全过程详解.doc

    《VC++动态链接库创建和调用全过程详解》这篇文档主要涵盖了动态链接库(DLL)在VC++环境下的创建和使用。DLL是一种重要的软件开发工具,它可以被多个应用程序共享,从而减少内存占用和提高程序效率。以下是文档的...

    动态链接库实验报告.pdf

    创建动态链接库需要进行一系列的步骤,主要包括: 1. 创建新项目:在开发环境中新建一个项目,为生成DLL做好准备。 2. 新建文件:新建所需的头文件和源文件,比如`TestDLL.h`和`TestDLL.cpp`。 3. 代码编写: - 在...

    Visual C++动态链接库

    Visual C++ 动态链接库是指在 Visual C++ 环境下开发和使用的动态链接库,动态链接库是一种共享代码的方式,可以提供给开发者一些可以直接使用的变量、函数或类。下面是对 Visual C++ 动态链接库的详细介绍。 首先...

    VC 动态链接库创建和调用全过程详解.docx

    【VC 动态链接库创建和调用全过程详解】 动态链接库(DLL,Dynamic Link Library)是Windows操作系统中的一种机制,允许程序在运行时动态加载和卸载代码库。DLL实质上是一个包含可由多个程序同时使用的函数和数据的...

    Fortran语言的动态链接库的开发及应用

    首先,需要在 Fortran PowerStation 开发环境中建立动态链接库的项目文件(IFCSW.MDP),然后编写动态链接库的源代码文件(IFCSW.F90),并将源代码文件插入到动态链接库的项目文件中。在动态链接库源代码(IFCSW.F90)中...

    C++动态链接库编程深入浅出

    ### C++动态链接库编程深入浅出 #### 概述 动态链接库(Dynamic Link Library,简称DLL)是在Microsoft Windows操作系统环境下的一种共享库文件格式。它允许开发者将多个应用程序所需的公共功能封装到一个单独的...

    Windows下动态链接库的创建和使用

    ### Windows下动态链接库的创建和使用 #### 一、动态链接库(DLL)概述 动态链接库(Dynamic Link Library,简称DLL)是Windows操作系统中一种重要的编程资源,它允许程序共享代码和数据。通过使用DLL,多个应用程序...

    动态链接库的基础教程

    动态链接库的创建涉及到导出函数、类或其他资源的定义,而使用动态链接库则需要导入这些导出项。 1. **创建动态链接库** - 使用Visual C++创建一个新的DLL项目。 - 定义要导出的函数或类,并使用特定的关键字(如...

    linux动态链接库示例

    总结来说,"linux动态链接库示例"是一个关于如何在Linux环境下使用C语言创建、编译和使用动态链接库(`.so`文件)的过程。通过理解这些步骤,开发者能够更好地管理和利用系统资源,提高软件的复用性和维护性。

Global site tag (gtag.js) - Google Analytics