SDK编程笔记 - DLL篇
1. 动态链接之含义
在链接应用程序时常使用所谓“静态链接”的方法,即将各个目标文件(.obj)、运行时函数库(.lib)以及已编译的资源文件(.res)链接到一起,形成一个可执行文件(.exe)。使用静态链接时,可执行文件需要使用的各种函数和资源都已包含到文件中。这样做的缺点是对于多个程序都使用的相同函数和资源要重复链接到exe文件中,使程序变大、占用内存增加。 “动态链接”是将一些公用的函数或资源组织成动态链接库文件(.dll),当某个需要使用dll中的函数或资源的程序启动时(准确的说是初始化时),系统将该dll映射到调用进程的虚拟地址空间、增加该dll的引用计数值,然后当实际使用到该dll时操作系统就将该dll载入内存;如果使用该dll的所有程序都已结束,则系统将该库从内存中移除。使用同一dll的各个进程在运行时共享dll的代码,但是对于dll中的数据则各有一份拷贝(当然也有在dll中共享数据的方法)。 动态链接库中可以定义两种函数:输出函数和内部函数。输出函数可以被其他模块调用,内部函数只能被动态链接库本身调用。动态链接库也可以输出数据,但这些数据通常只被它自己的函数所使用。
2. 动态链接的优点
→节约内存;
→使应用程序“变瘦”;
→可单独修改动态链接库而不必与应用程序重新链接;
→可方便实现多语言联合编程(比如用VC++写个dll,然后在VB中调用);
→可将资源打包;
→可在应用程序间共享内存
→......
3. 关于扩展名
动态链接库的标准扩展名是dll,其他如exe,drv,fon也可作为扩展名,但只有扩展名为dll的动态链接库才能被Windows自动载入。如果使用其它扩展名的动态链接库,则调用动态链接库的程序中必须使用LoadLibrary或LoadLibraryEx载入动态链接库模块。
4. 用SDK创建一个简单的dll文件
在VC++中选择新建一个Win32 Dynamic-Link Library。需要建立一个c/c++ head file和一个c/c++ source file并加入工程。头文件中内容为输出函数的声明,源文件中内容为DllMain函数和输出函数的定义。下面是一个最简单的例子。
//dlldemo.h #ifdef __cplusplus #define EXPORT extern "C" __declspec(dllexport) #else #define EXPORT __declspec(dllexport) #endif
EXPORT void CALLBACK DllFoo(void) ;
//dlldemo.c #include <windows.h> #include "dlldemo.h"
int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) { return TRUE ; }
EXPORT void CALLBACK DllFoo(void) { MessageBox(NULL,TEXT("This function is exported from a DLL"),TEXT("DllFoo"),MB_OK) ; return ; }
|
头文件预处理中的__declspec是微软增加的“C扩展类存储属性”(C Extended Storage-Class Attributes),它指明一个给出的实例被存储为一种微软特定的类存储属性,可以为thread,naked,dllimport或dllexport. [MSDN原文:The extended attribute syntax for specifying storage-class information uses the __declspec keyword, which specifies that an instance of a given type is to be stored with a Microsoft-specific storage-class attribute (thread, naked, dllimport, or dllexport).] 输出函数必须指明为CALLBACK。 DllMain是dll的入口点函数。也可以不写它。DllMain必须返回TRUE,否则系统将终止程序并弹出一个“启动程序时出错”对话框。 编译链接后,得到动态链接库文件dlldemo.dll和输入库文件dlldemo.lib。
5.使用dll的两种方式
方法一: load-time dynamic linking
在要调用dll的应用程序链接时,将dll的输入库文件(import library,.lib文件)包含进去。具体的做 法是在源文件开头加一句#include ,然后就可以在源文件中调用dlldemo.dll中的输出文件了。
方法二: run-time dynamic linking
不必在链接时包含输入库文件,而是在源程序中使用LoadLibrary或LoadLibraryEx动态的载入dll。
主要步骤为(以demodll.dll为例):
1) typedef函数原型和定义函数指针。 typedef void (CALLBACK* DllFooType)(void) ; DllFooType pfnDllFoo = NULL ;
|
2) 使用LoadLibrary载入dll,并保存dll实例句柄 HINSTANCE dllHandle = NULL ; ... dllHandle = LoadLibrary(TEXT("dlldemo.dll"));
|
3) 使用GetProcAddress得到dll中函数的指针 pfnDllFoo = (DllFooType)GetProcAddress(dllHandle,TEXT("DllFoo")) ; 注意从GetProcAddress返回的指针必须转型为特定类型的函数指针。 |
4)检验函数指针,如果不为空则可调用该函数 if(pfnDllFoo!=NULL) DllFoo() ;
|
5)使用FreeLibrary卸载dll FreeLibrary(dllHandle) ;
|
使用run-time dynamic linking 比较麻烦,但有它的好处(下面讨论)。MSDN中有一篇文章DLLs the Dynamic Way讨论使用c的宏创建一个基类pDll完成以上复杂的操作,使用时只需定义一个类继承自类pDll并 对类和函数使用宏。
以上两种方法都要求应用程序能找到dll文件,Windows按以下顺序寻找dll文件:
1)应用程序所在目录。 |
2)当前目录。 |
3)Windows 9x : System目录; Windows 2000/NT : System32 目录 |
4)Windows 2000/NT的System目录。 |
5)Windows所在目录。 |
6)环境变量path中的路径。 |
如果系统不能找到dll文件,将结束调用dll的进程并弹出一个“启动程序时出错”对话框,告诉你“找 不到所需的dll文件-XXX.dll”。
6 使用运行时的动态链接(Run-Time Dynamic Linking)有什么好处?
如果使用载入时的动态链接(Load-Time Dynamic Linking),当dll文件丢失时,调用此dll的程序将不能运行,你将会看到一个“启动程序时出错”对话框。而如果在运行时载入dll,你有机会处理这个错误,至少可以比较“温柔”的结束程序。
如果dll改变了,使用load-time dynamic linking的程序可能会终止,而使用run-time dynamic linking 的程序只有当调用的函数在新的dll中不存在时才会出错。
7 使用纯资源dll
一般只在其c文件中写一个空的DllMain,然后向工程中插入资源,最后编译为dll文件。纯资源dll没有任何输出函数,因此不会生成.lib文件,所以必须在运行时用LoadLibrary载入。
8 在dll中使用共享数据(摘自programming windows)
// shared memory section (requires /SECTION:shared,RWS in link options) #pragma data_seg ("shared") int iTotal = 0 ; WCHAR szStrings [MAX_STRINGS][MAX_LENGTH + 1] = { '/0' } ; #pragma data_seg ()
#pragma comment(linker,"/SECTION:shared,RWS") |
第一个#pragma叙述建立资料段,这里命名为shared。您可以将这段命名为任何一个您喜欢的名字。在这里的#pragma叙述之後的所有初始化了的变数都放在shared资料段中。第二个#pragma叙述标示段的结束。对变数进行专门的初始化是很重要的,否则编译器将把它们放在普通的未初始化资料段中而不是放在shared中。 连结器必须知道有一个「shared」共享资料段。在「Project Settings」对话方块选择「Link」页面标签。选中「STRLIB」时在「Project Options」栏位(在Release和Debug设定中均可),包含下面的连结叙述: /SECTION:shared,RWS 字母RWS表示段具有读、写和共用属性。或者,您也可以直接用DLL原始码指定连结选项,就像我们在STRLIB.C那样: #pragma comment(linker,"/SECTION:shared,RWS")
the end
分享到:
相关推荐
在SDK中,开发者可以找到诸如` quartz.dll `这样的系统组件,它们实现了许多基础的滤镜,例如源滤镜(Source Filter)、解码滤镜(Decoder Filter)、渲染滤镜(Renderer Filter)等。SDK还提供了GraphEdit工具,这...
- A1设备使用HTC的重力感应方案,相关的DLL为HTCSensorSDK.dll,提供了HTCSensorOpen、HTCSensorGetDataOutput和HTCSensorClose三个函数。 - 开发者可以通过HTCSensorOpen打开重力感应器,并通过...
根据给定的文件信息,我们可以总结出一系列关于C++及其在Windows编程环境下应用的重要知识点,尤其是围绕孙鑫视频VC++深入详解的学习笔记。下面将详细展开这些知识点。 ### C++深入详解笔记概述 #### Windows程序...
10. **dll**:这里提到的dll文件,很可能是虹软SDK的动态链接库文件,这些文件包含了人脸识别的实现代码,通过引用它们,C#代码能够调用SDK的功能。 在实际开发过程中,`Form1.cs`会使用ArcSoft SDK提供的API来完成...
- **学习建议**: 在学习本书之前,推荐先学习一些关于WINDOWS 32位编程的知识,至少能够使用纯SDK编写简单的应用程序。 #### 二、WINDOWS应用程序基础知识 - **WinMain函数**: WINDOWS应用程序的核心入口点,用于...
不过,如果你的项目涉及读写OpenXML文档,理解OpenXML的结构和.NET的OpenXML SDK会很有用。 总的来说,深入研究`wpfgfx_cor3.dll`需要对.NET Framework、WPF架构、XAML以及图形渲染有较深的理解。通过阅读源代码,...
总的来说,《VC++技术内幕》的学习笔记强调了理论与实践的结合,从WinMain函数到MFC框架,从GDI到DLL,再到源代码浏览器的使用,每一个知识点都是Windows平台上高效编程的基础。通过深入学习和实践,开发者可以提升...
### VC++深入学习笔记知识点概览 #### Lesson1: Windows程序运行原理及程序编写流程 - **窗口产生过程**:Windows程序的核心在于窗口的管理和消息处理。每一个窗口都是由一个句柄标识,句柄(HWND)是Windows用来...
/* 你能看得出来,这不是一篇正规的技术文章,所以若你不小心从里边读到了一个爱情故事,可不要奇怪。有很多人用程序来表述爱情,在其中我能看到有Money,有Girl,有一些还涉及到Sex,但是我没有找到Love,我始终相信...
2012-06-12 11:55 3,721,136 VC++动态链接库(dll)编程深入浅出.rar 2012-06-12 13:02 23,185 VC++图像平滑处理+程序.rar 2012-06-12 12:12 45,056 VC++操作INI配置文件的实现.doc 2012-06-12 11:48 11,728,284 VC++...
【Visual C# 从入门到精通学习笔记】涵盖了C#编程的基础知识,包括开发环境、.NET平台介绍、C#程序开发等多个方面。以下是对这些知识点的详细解释: 1. **开发、运行环境**: - **快速应用开发工具(RAD)**:用于...
这篇学习笔记将带你深入理解C#编程的基础,从安装开发环境到掌握核心概念,一步步成为C#编程的专家。 一、开发、运行环境 1. 快速应用开发工具(Rapid Application Development,RAD):RAD工具旨在简化和加速应用...
MEX文件本质上是动态链接库(DLL),它们能够被MATLAB解释器无缝调用,从而在执行速度上远超纯MATLAB代码。这种混合编程模式对于处理大数据或高性能计算任务尤其有用,因为它能够减少数据在MATLAB和底层系统之间的...
在描述中提到的"博文win32笔记(一)参考程序(win32)的配套程序",意味着这个压缩包可能包含了一个或多个示例程序,这些程序与一篇介绍Win32编程的博客文章相关联。通常,这样的示例代码会解释如何实现特定的Win32 ...
这份笔记可能是基于《VC++技术内幕》这本书的阅读和实践积累,作者强调在研读此书之前,最好具备一定的Windows 32位编程基础,尤其是能够运用纯SDK(Software Development Kit)编写简单的应用程序。 VC++是...
在阅读这本书之前,建议读者具备Windows 32位编程的基础,至少能够使用Software Development Kit (SDK)编写简单的程序。 第一天的学习内容聚焦于Windows应用程序的基础。书中指出,每个Windows应用程序都需要包含`...
在后续的笔记中,可能涵盖Symbian操作系统的基础概念、S60平台特性、UI设计、应用程序编程接口(API)使用、内存管理、线程与同步、网络编程、数据库访问、设备访问、系统服务调用等多个方面。此外,还会涉及到调试...