Windows ダイナミックリンクライブラリ内の DllMain 関数から直接的または間接的に ODBC 関数を呼び出さないでください。DllMain のエントリポイント関数は、簡単な初期化および終了処理のみを実行するためのものです。SQLFreeHandle、SQLFreeConnect、SQLFreeEnv などの ODBC 関数を呼び出した場合、デッドロックや循環依存が発生する可能性があります。
適切でないプログラミングコードの例を次に示します。Microsoft ODBC ドライバーマネージャーは、SQL Anywhere ODBC ドライバーへの最後のアクセスが完了したことを検出すると、ドライバーのアンロードを実行します。SQL Anywhere ODBC ドライバーが停止すると、アクティブなスレッドがすべて停止します。スレッドの終了の結果、DllMain への再帰的なスレッド detach 呼び出しが発生します。DllMain への呼び出しは直列化されていて、呼び出しが進行中であるため、新しいスレッド detach 呼び出しが開始されることはありません。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 ) { HENV tls_henv; HDBC tls_hdbc; tls_henv = (HENV) handles[0]; tls_hdbc = (HDBC) 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 */ } |
DLL を作成する際のベストプラクティスの詳細については、 http://msdn.microsoft.com/en-us/windows/hardware/gg487379.aspx にある Microsoft のホワイトペーパーを参照してください。
![]() |
DocCommentXchange で意見交換できます
|
Copyright © 2012, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.1 |