不应在 Windows 动态链接库中从 DllMain 函数直接或间接调用 ODBC 函数。DllMain 入口点函数只用于执行简单初始化和终止任务。调用 SQLFreeHandle、SQLFreeConnect 和 SQLFreeEnv 等 ODBC 函数可能形成死锁和循环相关性。
以下代码示例为糟糕的编程实践。当 Microsoft ODBC 驱动程序管理器发现已经完成对 SQL Anywhere ODBC 驱动程序的最后一次访问,它会卸载驱动程序。当 SQL Anywhere ODBC 驱动程序关闭时,它也停止了所有活动线程。线程终止导致对 DllMain 的递归线程分离调用。由于 DllMain 调用已序列化并且正在执行调用,将永远不会启动新线程分离调用。SQL Anywhere ODBC 驱动程序会永远等待线程终止,并且应用程序会挂起。
BOOL APIENTRY DllMain( HMODULE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) { HANDLE *handles; switch( fdwReason ) { . . . case DLL_THREAD_DETACH: /* do thread cleanup */ handles = (HANDLE *) TlsGetValue( TlsIndex ); if( handles != NULL ) { SQLHENV tls_henv; SQLHDBC tls_hdbc; tls_henv = (SQLHENV) handles[0]; tls_hdbc = (SQLHDBC) handles[1]; if( tls_hdbc != NULL ) SQLFreeHandle( SQL_HANDLE_DBC, tls_hdbc ); if( tls_henv != NULL ) SQLFreeHandle( SQL_HANDLE_ENV, tls_henv ); handles[0] = NULL; handles[1] = NULL; } break; . . . } return TRUE; /* indicate success */ } |
有关详细信息,请阅读 Microsoft 白皮书Best Practices for Creating DLLs,网址为 http://msdn.microsoft.com/zh-cn/windows/hardware/gg487379.aspx。
![]() |
使用DocCommentXchange讨论此页。
|
版权 © 2013, SAP 股份公司或其关联公司. - SAP Sybase SQL Anywhere 16.0 |