Dynamic-Link库 (DLL) 可以包含全局数据或本地数据。
在 DLL 源代码文件中声明为全局的变量由编译器和链接器视为全局变量,但加载给定 DLL 的每个进程都将获取该 DLL 的全局变量的副本。 静态变量的范围仅限于声明静态变量的块。 因此,默认情况下,每个进程都有自己的 DLL 全局变量和静态变量实例。
开发工具可能允许重写默认行为。 例如,Visual C++ 编译器支持
#pragma节
,链接器支持 /SECTION 选项。 有关详细信息,请参阅开发工具中包含的文档。
动态内存分配
当 DLL 使用任何内存分配函数分配内存时, (
GlobalAlloc
、
LocalAlloc
、
HeapAlloc
和
VirtualAlloc
) ,则会在调用进程的虚拟地址空间中分配内存,并且只能访问该进程的线程。
DLL 可以使用文件映射来分配可在进程之间共享的内存。 有关如何使用文件映射创建命名共享内存的一般讨论,请参阅
文件映射
。 有关使用
DllMain
函数使用文件映射设置共享内存的示例,请参阅
在Dynamic-Link库中使用共享内存
。
线程本地存储
线程本地存储 (TLS) 函数使 DLL 能够分配索引以存储和检索多线程进程的每个线程的不同值。 例如,每当用户打开新电子表格时,电子表格应用程序都可以创建同一线程的新实例。 为各种电子表格操作提供函数的 DLL 可以使用 TLS 保存有关每个电子表格的当前状态的信息, (行、列等) 。 有关线程本地存储的一般讨论,请参阅
线程本地存储
。 有关使用
DllMain
函数设置线程本地存储的示例,请参阅
Dynamic-Link库中的“使用线程本地存储
”。
Windows Server 2003 和 Windows XP:
Visual C++ 编译器支持一种语法,可用于声明线程局部变量:
_declspec (线程)
。 如果在 DLL 中使用此语法,则无法在 Windows Vista 之前的 Windows 版本中显式使用
LoadLibrary
或
LoadLibraryEx
加载 DLL。 如果 DLL 将显式加载,则必须使用线程本地存储函数,而不是
_declspec (线程)
。