C++动态链接库编程深入浅出
- 格式:pdf
- 大小:466.90 KB
- 文档页数:24
第4节我们对非MFC DLL进行了介绍,这一节将详细地讲述MFC规则DLL的创建与使用技巧。
另外,自从本文开始连载后,收到了一些读者的e-mail。
有的读者提出了一些问题,笔者将在本文的最后一次连载中选取其中的典型问题进行解答。
由于时间的关系,对于读者朋友的来信,笔者暂时不能一一回复,还望海涵!由于笔者的水平有限,文中难免有错误和纰漏,也热诚欢迎读者朋友不吝指正!MFC规则DLL的概念体现在两方面:(1)它是MFC的“是MFC的”意味着可以在这种DLL的内部使用MFC;(2)它是规则的“是规则的”意味着它不同于MFC扩展DLL,在MFC规则DLL的内部虽然可以使用MFC,但是其与应用程序的接口不能是MFC。
而MFC扩展DLL与应用程序的接口可以是MFC,可以从MFC扩展DLL中导出一个MFC类的派生类。
Regular DLL能够被所有支持DLL技术的语言所编写的应用程序调用,当然也包括使用MFC的应用程序。
在这种动态连接库中,包含一个从CWinApp继承下来的类,DllMain 函数则由MFC自动提供。
Regular DLL分为两类:(1)静态链接到MFC 的规则DLL静态链接到MFC的规则DLL与MFC库(包括MFC扩展DLL)静态链接,将MFC 库的代码直接生成在.dll文件中。
在调用这种DLL的接口时,MFC使用DLL的资源。
因此,在静态链接到MFC 的规则DLL中不需要进行模块状态的切换。
使用这种方法生成的规则DLL其程序较大,也可能包含重复的代码。
(2)动态链接到MFC 的规则DLL动态链接到MFC 的规则DLL 可以和使用它的可执行文件同时动态链接到MFC DLL 和任何MFC扩展DLL。
在使用了MFC共享库的时候,默认情况下,MFC使用主应用程序的资源句柄来加载资源模板。
这样,当DLL和应用程序中存在相同ID的资源时(即所谓的资源重复问题),系统可能不能获得正确的资源。
因此,对于共享MFC DLL的规则DLL,我们必须进行模块切换以使得MFC能够找到正确的资源模板。
VC++动态链接库(DLL)编程VC++动态链接库(DLL)编程(一)――理解库作者:宋宝华e-mail:21cnbao@1.概论先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。
在仓库的发展史上经历了“无库-静态链接库-动态链接库”的时代。
静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中了。
但是若使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。
静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。
对动态链接库,我们还需建立如下概念:(1)DLL 的编制与具体的编程语言及编译器无关只要遵循约定的DLL接口规范和调用方式,用各种语言编写的DLL都可以相互调用。
譬如Windows提供的系统DLL(其中包括了Windows的API),在任何开发环境中都能被调用,不在乎其是Visual Basic、Visual C++还是Delphi。
(2)动态链接库随处可见我们在Windows目录下的system32文件夹中会看到kernel32.dll、user32.dll和gdi32.dll,windows的大多数API都包含在这些DLL中。
kernel32.dll中的函数主要处理内存管理和进程调度;user32.dll中的函数主要控制用户界面;gdi32.dll中的函数则负责图形方面的操作。
一般的程序员都用过类似MessageBox的函数,其实它就包含在user32.dll这个动态链接库中。
由此可见DLL对我们来说其实并不陌生。
(3)VC动态链接库的分类Visual C++支持三种DLL,它们分别是Non-MFC DLL(非MFC动态库)、MFC Regular DLL(MFC规则DLL)、MFC Extension DLL(MFC扩展DLL)。
动态链接库教程动态链接库(Dynamic Link Library,简称DLL)是一种可由多个程序共享的库文件,它包含了一组函数和数据,可以在程序运行时加载和调用。
DLL 文件可用于将一些通用的功能封装成函数,供多个程序调用,从而提高代码的复用性和开发效率。
本文将详细介绍动态链接库的概念、使用方法以及制作过程。
一、动态链接库的概念动态链接库是一种包含了函数和数据的库文件,它可以在程序运行时被加载和调用。
与静态链接库相比,动态链接库的优势在于节省内存空间和提高代码的复用性。
当多个程序需要使用同一个功能时,它们可以共享同一个DLL文件,避免了重复编写相同的代码。
二、动态链接库的使用方法在使用动态链接库之前,我们首先需要了解动态链接库的编译、加载和调用过程。
1.编译动态链接库在创建 DLL 文件时,我们需要按照一定的规范编写代码,并将其编译成 DLL 文件。
编译时,需要指定导出函数的修饰符(如 _stdcall、_cdecl等),以及导出函数的声明。
这些步骤可以在开发环境(如Visual Studio)中完成。
2.加载动态链接库在程序运行时,需要加载 DLL 文件。
我们可以通过调用LoadLibrary 函数来加载 DLL,该函数返回一个句柄,表示 DLL 的实例。
加载 DLL 文件后,我们可以通过该句柄获取 DLL 中导出函数的地址。
3.调用动态链接库在获取到DLL中导出函数的地址后,我们可以通过函数指针来调用DLL中的函数。
通过函数指针,程序可以跳转到DLL中执行指定的函数,从而完成相应的功能。
三、制作动态链接库下面以C++语言为例,简单介绍如何制作一个动态链接库。
1.创建DLL工程在 Visual Studio 中创建一个 DLL 项目,选择 DLL(动态链接库)作为项目类型。
在项目中添加需要导出的函数,并在头文件中进行声明。
2.编写导出函数在 DLL 项目中编写需要导出的函数,并在函数前添加修饰符(如_stdcall、_cdecl等)。
VC++动态链接库(DLL)编程――理解库作者:宋宝华e-mail:21cnbao@1.概论先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL 看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。
在仓库的发展史上经历了“无库-静态链接库-动态链接库”的时代。
静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中了。
但是若使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE 独立的DLL文件。
静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。
对动态链接库,我们还需建立如下概念:(1)DLL的编制与具体的编程语言及编译器无关只要遵循约定的DLL接口规范和调用方式,用各种语言编写的DLL都可以相互调用。
譬如Windows提供的系统DLL(其中包括了Windows的API),在任何开发环境中都能被调用,不在乎其是Visual Basic、Visual C++还是Delphi。
(2)动态链接库随处可见我们在Windows目录下的system32文件夹中会看到kernel32.dll、user32.dll 和gdi32.dll,windows的大多数API都包含在这些DLL中。
kernel32.dll中的函数主要处理内存管理和进程调度;user32.dll中的函数主要控制用户界面;gdi32.dll中的函数则负责图形方面的操作。
一般的程序员都用过类似MessageBox的函数,其实它就包含在user32.dll 这个动态链接库中。
由此可见DLL对我们来说其实并不陌生。
(3)VC动态链接库的分类Visual C++支持三种DLL,它们分别是Non-MFC DLL(非MFC动态库)、MFC Regular DLL(MFC规则DLL)、MFC Extension DLL(MFC扩展DLL)。
C语言动态链接库编程VB6中引用VC6编写的.DLL函数进行屏幕绘图一、动态链接库的基本概念动态链接库(Dynamic Link Library,简称DLL)是由函数对象以及资源组成的二进制库文件,此库文件能同时被多个进程或者应用程序使用。
图1、VB6中使用.dll库函数在窗体中绘制简单飞机模型上图1展现了在VB6中调用VC6建立的屏幕绘图动态链接库(.DLL)的应用效果,程序的运行非常顺畅;实现了在VB中绘图象在VC中一样的效果(3D+消隐+光照)。
二、动态链接库不可少的两个文件1. 创建动态库的函数源文件(.cpp):编写库函数源码的源文件。
2. 导出函数名字的文件(.def):编写Lib(*.dll)入口函数名字的源文件。
三、编程创建动态链接库下面以简单的屏幕绘图函数为例,实现用VC6创建动态链接库,在VB6中调用(.dll)函数的全过程。
1. 打开VC6:文件-新建-工程(空工程)图2、新建Win32 DLL工程2. 添加(.cpp)文件到工程(Graph.cpp)图3、新建Graph.cpp文件并添加到工程3. 添加(.def)文件到工程(Graph.def)图4、新建Graph.def文件并添加到工程4.在Graph.cpp文件中编写函数源码#ifndef WIN32GDI_API#define WIN32GDI_API _declspec(dllexport)#define EXC extern "C"#define CALL _stdcall#endif#include <windows.h>#include <stdio.h>#include <math.h>typedef struct _tagSIZE2I{int width;int height;}SIZE2I;typedef struct _tagCOLOR4U{unsigned char b;unsigned char g;unsigned char r;unsigned char a;}COLOR4U;typedef struct _tagCOLOR4I{int b;int g;int r;int a;}COLOR4I;HDC _g_hDC;COLOR4U *_g_bitmap;COLOR4I _g_ftcolor;COLOR4I _g_bkcolor;SIZE2I _g_size={300,200};SIZE2I _g_oldsize={-100,-100};int _g_win_test=0;EXC WIN32GDI_API void CALL SetGraphicsDC(HDC shdc){_g_hDC=shdc;}EXC WIN32GDI_API void CALL InitGraph(int w,int h){if(w<200)w=200;if(h<180)h=180;_g_size.width=w;_g_size.height=h;if(_g_win_test==1){if(_g_size.width!=_g_oldsize.width||_g_size.height!=_g_oldsize.height){ _g_oldsize=_g_size;delete []_g_bitmap;_g_bitmap=new COLOR4U [_g_size.width*_g_size.height];}}if(_g_win_test==0){_g_oldsize=_g_size;_g_bitmap=new COLOR4U [_g_size.width*_g_size.height];_g_win_test=1;}}int TestNumber(int number){if(number>255) number=255;if(number<0) number=0;return number;}COLOR4I GetColor4i(int r,int g,int b,int a){COLOR4I cr={b,g,r,a};return cr;}EXC WIN32GDI_API void CALL SetColor(int r,int g,int b){r=TestNumber(r);g=TestNumber(g);b=TestNumber(b);_g_ftcolor=GetColor4i(r,g,b,0);}EXC WIN32GDI_API void CALL SetBackColor(int r,int g,int b){r=TestNumber(r);g=TestNumber(g);b=TestNumber(b);_g_bkcolor=GetColor4i(r,g,b,0);}EXC WIN32GDI_API void CALL Flush(){HBITMAP _cgl_bitmap=CreateBitmap(_g_size.width,_g_size.height,1,32,_g_bitmap);HBRUSH hb=CreatePatternBrush(_cgl_bitmap);SelectObject(_g_hDC,hb);Rectangle(_g_hDC,10,10,_g_size.width-25,_g_size.height-50);DeleteObject(hb);DeleteObject(_cgl_bitmap);}COLOR4U GetColor4u(COLOR4I ci){COLOR4U ti={ci.b,ci.g,ci.r,ci.a};return ti;}EXC WIN32GDI_API void CALL Clear(){int len,i;COLOR4U tm=GetColor4u(_g_bkcolor);len=_g_size.width*_g_size.height;for(i=0;i<len;i++){_g_bitmap[i]=tm;}}EXC WIN32GDI_API void CALL SetPixel2i(int x,int y){COLOR4U tm;tm=GetColor4u(_g_ftcolor);if(x>=0&&x<_g_size.width-1&&y>=0&&y<_g_size.height-1){int len=y*_g_size.width+x;_g_bitmap[len]=tm;}}EXC WIN32GDI_API void CALL Line2Di (int x1,int y1,int x2,int y2){int i,len;float dx,dy,x,y;x=(float)x1;y=(float)y1;if(abs(x2-x1)>=abs(y2-y1))len=abs(x2-x1);elselen=abs(y2-y1);SetPixel2i((int)x,(int)y);dx=(float)(x2-x1)/len;dy=(float)(y2-y1)/len;for(i=1;i<=len;i++){x+=dx;y+=dy;SetPixel2i((int)x,(int)y);}}5. 在Graph.def文件中编写Lib(*.dll)入口函数名字的源文件LIBRARY GraphEXPORTSSetGraphicsDCInitGraphSetColorSetBackColorFlushClearSetPixel2iLine2Di6. 编译动态链接库文件图5、成功编译Graph.dll7. 把生成的Graph.dll文件拷贝到C:\Windows\System中(Win7系统)8. 打开VB6:新建工程-标准EXE图6、VB工程源码屏幕截图9. 运行工程图7、VB工程执行结果屏幕截图至此就完成了从编写动态链接库到调用库的全过程。
您正在看的VC教程是:关于VC中的DLL的编程。
在我们实际用软件时,经常可看到许多动态连接库。
动态连接库有其自身的优点如节省内存、支持多语种等功能,而且,当DLL中的函数改变后,只要不是参数的改变调用起的函数并不需要重新编译。
这在编程时十分有用。
至于其他妙处,各位在电脑杂志、书籍中都能看到,我这里再说就是废话了.这次小弟我所要讲的是如何在VC5.0中如何做自己的Win32 DLLs,各位要做自己的动态连接库,首先要知道DLL在VC5.0中都有哪几种分类。
VC支持三种DLL,它们是:1.Non-MFC Dlls2.Regular Dlls3.Extension Dlls Note:翻译措辞不当,故遇到术语是引用原词Non-MFC DLL:指的是不用MFC的类库结构,直接用C语言写的DLL,其输出的函数一般用的是标准C接口,并能被非MFC或MFC编写的应用程序所调用。
LL,Regular DLL:和下述的Extension Dlls一样,是用MFC类库编写的。
明显的特点是在源文件里有一个继承CWinApp的类。
其又可细分成静态连接到MFC和动态连接到MFC 上的。
但静态连接到MFC的动态连接库只被VC的专业般和企业版所支持。
Extension DLL:用来实现从MFC所继承下来的类的重新利用,也就是说,用这种类型的动态连接库,可以用来输出一个从MFC所继承下来的类。
Extension DLL使用MFC 的动态连接版本所创建的,并且它只被用MFC类库所编写的应用程序所调用。
各位看到这里如果眼有点花或头有点晕,请别泄气,再看两遍,然后继续往下看,定有收获。
标题: 关于VC中的DLL的编程[1]这一节介绍Non-MFC DLLs的编写方法。
下面是一个通用的写法: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;}每一个DLL必须有一个入口点,这就象我们用C编写的应用程序一样,必须有一个WINMAIN函数一样。
c语言编译的链接文件解析C语言编译的链接文件解析一、引言在C语言编程中,链接是将多个目标文件合并为一个可执行文件的过程。
链接文件的作用是将程序中的各个模块进行组合,解决模块之间的引用关系,使得程序能够正确地运行。
本文将介绍C语言编译的链接文件解析的相关知识。
二、链接的基本概念链接是将编译器生成的目标文件与库文件进行合并,生成可执行文件的过程。
链接分为静态链接和动态链接两种方式。
1. 静态链接静态链接是将所有的目标文件和库文件的代码和数据合并到一个可执行文件中。
在静态链接的过程中,连接器将目标文件中的符号引用与符号定义进行匹配,将符号引用替换为符号定义的地址,最终生成可执行文件。
静态链接的优点是生成的可执行文件独立存在,不依赖于其他文件;缺点是可执行文件的体积比较大。
2. 动态链接动态链接是在运行时将目标文件和库文件的代码和数据加载到内存中,生成可执行文件的过程。
在动态链接的过程中,连接器只处理符号引用与符号定义的匹配关系,生成一个包含符号引用的表格。
在程序运行时,操作系统根据这个表格将符号引用替换为符号定义的地址。
动态链接的优点是可执行文件的体积小,共享库可以被多个程序共享;缺点是程序依赖于共享库,如果共享库缺失或版本不兼容,程序将无法运行。
三、链接文件的结构链接文件一般包含以下几个部分:1. 文件头(File Header):记录了链接文件的一些基本信息,如文件的魔数、版本号等。
2. 段表(Section Header Table):记录了链接文件中各个段的信息,如段的起始地址、大小等。
3. 符号表(Symbol Table):记录了链接文件中定义和引用的符号的信息,如符号的名称、类型、地址等。
4. 重定位表(Relocation Table):记录了链接文件中需要进行重定位的位置和相关信息,用于将目标文件中的符号引用替换为符号定义的地址。
5. 字符串表(String Table):记录了链接文件中使用的字符串,如符号的名称、段的名称等。
1.概论先来阐述一下DLL(Dynamic Linkable Library)的概念.你可以简单的把DLL看成一种仓库.它提供给你一些可以直接拿来用的变量、函数或类。
在仓库的发展史上经历了“无库-静态链接库-动态链接库”的时代。
静态链接库与动态链接库都是共享代码的方式.如果采用静态链接库.则无论你愿不愿意.lib中的指令都被直接包含在最终生成的EXE文件中了。
但是若使用DLL.该DLL不必被包含在最终EXE文件中.EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL 文件。
静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库.而在动态链接库中还可以再包含其他的动态或静态链接库。
对动态链接库.我们还需建立如下概念:(1)DLL 的编制与具体的编程语言及编译器无关只要遵循约定的DLL接口规范和调用方式.用各种语言编写的DLL都可以相互调用。
譬如Windows提供的系统DLL(其中包括了Windows的API).在任何开发环境中都能被调用.不在乎其是Visual Basic、Visual C++还是Delphi。
(2)动态链接库随处可见我们在Windows目录下的system32文件夹中会看到kernel32.dll、user32.dll和gdi32.dll.windows的大多数API都包含在这些DLL中。
kernel32.dll中的函数主要处理内存管理和进程调度;user32.dll中的函数主要控制用户界面;gdi32.dll中的函数则负责图形方面的操作。
一般的程序员都用过类似MessageBox的函数.其实它就包含在user32.dll这个动态链接库中。
由此可见DLL对我们来说其实并不陌生。
(3)VC动态链接库的分类Visual C++支持三种DLL.它们分别是Non-MFC DLL(非MFC动态库)、MFC Regular DLL (MFC规则DLL)、MFC Extension DLL(MFC扩展DLL)。