设为首页 加入收藏

TOP

22.2.4 动态链接库函数
2013-10-07 13:11:00 来源: 作者: 【 】 浏览:60
Tags:22.2.4 动态 链接 函数

22.2.4  动态链接库函数

Win32中提供了有关动态链接库的函数。下面做个简要介绍。DisableThread LibraryCalls()函数关闭hLibModule句柄指定的动态链接库的dll_thread_attach和dll_thread_detach的通知消息。可以减少一些应用程序的工作代码区的大小。函数原型为:

  1. BOOL DisableThreadLibraryCalls(  
  2. HMODULE hLibModule);    // hLibModule参数指定了要关闭消息的模块 

如果hLibModule指定的DLL有活动的静态线程局部存储区或者hLibModule是一个无效的模块句柄,则函数会失败。要获取具体的错误原因,可以通过调用GetLastError()函数获得。

DllMain是库定义函数名称的占位符,是DLL可选的入口方法。早期的SDK使用DllEntryPoint作为入口函数名。当构建DLL时,必须指定使用的实际名称。当进程和线程初始化或终止时,或调用LoadLibrary()和FreeLibrary()函数时,系统会调用此函数。函数原型是:

  1. BOOL WINAPI DllMain(  
  2.   HINSTANCE hinstDLL,   // DLL模块的句柄  
  3.   DWORD fdwReason,      // 调用函数的来源  
  4.   LPVOID lpvReserved    // 预留  
  5. ); 

其中,fdwReason参数指定DLL入口函数被调用的来源,取值如表22-1所示。

表22-1  入口函数来源


当系统使用dll_process_attach值调用DllMain()函数时,如果成功返回true,否则返回false。当进程使用LoadLibrary()函数调用DllMain()函数时,如果返回值为false,则LoadLibrary()函数返回NULL。当在进程初始化时调用DllMain()函数时,如果返回值为false,则进程会报告错误并终止进程。要获取更多的错误信息,可以使用GetLastError()函数获取。

FreeLibrary()函数减少装载的DLL模块的引用数目。当引用数目达到0时,模块将从调用进程的地址空间中卸载,并且句柄不再有效。

  1. BOOL FreeLibrary( HMODULE hLibModule)   // 装载的库模块的句柄 

每个进程为每个装载的库模块维护一个引用数目。每调用一次LoadLibrary()函数,引用数目增加一,每调用一次FreeLibrary()函数引用数目减一。因为装载时动态链接有一个引用数目,DLL模块在进程初始化装载。如果调用LoadLibrary()函数装载相同模块,则数目增加。

在卸载库模块以前,如果有入口函数,系统使用dll_process_detach值调用DLL的DllMain()函数使得DLL从进程中分离。这样使得DLL可以有机会清除当前进程分配的资源。在入口函数返回后,库模块从当前进程的地址空间中移除。

从DllMain()函数中调用FreeLibrary是不安全的。调用FreeLibrary()函数不会影响其他使用相同库模块的进程。FreeLibraryAndExitThread()函数会减少装载的DLL的引用数目一次,然后调用ExitThread()函数终止调用线程。此函数没有返回值。此函数给使用动态链接库创建和执行的线程一个安全的卸载DLL并终止它们的时机。函数原型为:

  1. VOID FreeLibraryAndExitThread(  
  2.   HMODULE hLibModule,       // 要减少引用次数的动态链接库  
  3.   DWORD dwExitCode);        // 线程退出代码 

GetModuleFileName()函数返回执行文件包含的指定的模块的完整路径和文件名。函数原型为:

  1. DWORD GetModuleFileName(  
  2.   HMODULE hModule,          // 要获取文件名的模块句柄  
  3.   LPTSTR lpFilename,        // 接收模块路径的缓冲区的指针  
  4.   DWORD nSize );            // 缓冲区的大小 

如果模块装载到两个进程中,在一个进程中的模块名称可能会与在另一个进程中的模块名称不同。如果文件已经映射到调用进程的地址空间中,则GetModuleHandle()函数返回指定模块的模块句柄。函数原型为:

  1. HMODULE GetModuleHandle( LPCTSTR lpModuleName)  // 要获
    取句柄的模块的名称地址 

如果函数成功,则返回值为指定模块的句柄。如果函数失败,返回值为NULL。要获取更多的错误信息,可以调用GetLastError()函数获取。

GetProcAddress()函数返回导出的DLL函数的地址。函数原型为:

  1. FARPROC GetProcAddress( HMODULE hModule,       
    // DLL模块的句柄  
  2.   LPCSTR lpProcName);               // 函数名 

LoadLibrary()函数映射指定的可执行模块到调用进程的地址空间中。其函数原型为:

  1. HINSTANCE LoadLibrary( LPCTSTR lpLibFileName);  
    // 可执行模块的文件名的地址 

如果函数成功,则返回模块的句柄。如果函数失败,则返回值为NULL。要获取更多的错误信息,可以通过GetLastError()函数获取。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇22.2.3 应用程序链接DLL 下一篇22.2.2 DLL的导出

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: