动态链接库的数据
DLL可以包含全局数据及局部数据
变量范围DLL变量的默认范围与应用程序所声明的变量作用域相同,DLL源文件中的全局变量对于使用DLL的每个进程是全部可见的。静态变量受限于声明所在块范畴。默认情况下,每个进程具有自己的DLL全局变量及静态变量实例。
你所使用的开发工具可能会允许你超越默认的全局及静态变量范围。更多信息参见开发工具相关文档。
动态内存分配
当DLL用内存分配函数(GlobalAlloc、LocalAlloc、HeapAlloc及VirtualAlloc)分配内存时,被分配的内存处于调用进程的虚地址空间中,并且仅能被该进程的线程访问。
DLL可以使用文件映像来分配可在进程间共享的内存。关于如何利用文件映像创建共享命名存储空间的全面论述,可参照“文件映像”。查看应用DllMain函数设立文件映像的共享内存,参照“在动态链接库中使用共享内存”。
线程局部存储
一个多线程进程中的每个线程利用线程局部存储(TLS)函数,可以让DLL通过为多线程进程中每个线程分配存储及检索不同值的索引。例如,一个电子表格程序中每当用户打开一个新的电子表格时,就在同一线程中创建一个新的实例。为各种电子表格操作提供函数的DLL可以通过TLS保存每个电子表格的当前状态(行、列等等)。关于TLS更为全面的论述,可参照“线程局部存储”。关于通过DllMain函数建立线程局部存储的示例,可参照“在动态链接库中使用线程局部存储”。
警告: Visual C++ 编译器中可以利用_declspec(thread)来声明线程局部变量,如果应用该语法,就不能通过LoadLibrary或LoadLibraryEx函数明确载入DLL了。如果需要通过函数明确载入DLL的话,就必须通过线程局部存储函数来实现,而不是_declspec(thread)。
动态链接库重定向当应用程序载入一个与已装载版本不同的DLL时,问题就会产生。如果是在Windows 2000中运行的话,你可以通过创建一个重定向文件以使用正确版本的DLL。重定向文件的内容会被忽略,但如果它存在的话,(系统)就会强制从应用程序所在目录载入所有DLL。
重定向文件必须按如下格式命名:
appname.local
例如,如果应用程序的名字为editor.exe,重定向文件的名称应该为editor.exe.local。你必须把editor.exe.local安装到editor.exe所在的同一目录下,也必须把DLL安装到同一目录下。
如果重定向文件存在的话,LoadLibrary及LoadLibraryEx 函数就会改变搜索次序。如果指定了路径,而且重定向文件也指定,这些函数会在应用程序的目录中搜寻DLL。如果DLL在应用程序目录中,这些函数会忽略指定的路径,并载入程序目录下的DLL。如果不在程序目录下,函数将按指定目录载入DLL。
比如,一个应用程序c:\myapp\myapp.exe用以下路径调用了LoadLibrary:
c:\program files\common files\system\mydll.dll.
如果c:\myapp\myapp.exe.local以及c:\myapp\mydll.dll都存在,LoadLibrary 将载入c:\myapp\mydll.dll;否则,就载入c:\program files\common files\system\mydll.dll。
注意: 要养成把所需的DLL安装到应用程序相同目录中的好习惯,即便不需要使用重定向也是如此。这样就会保障你的程序不会覆盖其他DLL拷贝,当然也就不会导致其他应用程序错误产生。另外,其他应用程序也就不会覆盖你的DLL拷贝而导致你的应用程序运行失败。