システムで思わぬところでエラーになって、俺関係ないやん?
そういう事ありません?
今回は、Windows の 通信Socket の初期化と終了処理でやらかした話を書きます。
ソース中の一箇所、WSACleanup の呼び出し場所が間違っていました。
正しくないコード
#include <winsock2.h> void simpleSend( const char* str ) { WSADATA wsaData; if( !WSAStartup(MAKEWORD(2,0), &wsaData) ) { // 送信処理 } WSACleanup(); // 初期化に失敗したのにクリーンナップが呼び出される。 return 0; }
これだと、WSAStartup に失敗した時も WSACleanup が呼び出されてしまいます。
WSAStartup と WSACleanup の処理は、コールカウント方式で処理されます。従って、サードパーティ製のDLLで WSAStartup していたコードが巻き添えを食らって WSACleanup されてしまうため、Socket の close 処理時にエラーになってしまうという現象となりました。
WSAStartup が失敗するタイミングとしては、アプリケーション終了間際があります。アプリケーションの終了間際にサードパーティ製のDLLが例外を送出してしまうのですが、この原因が WSAStartup が失敗したにも関わらず、WSACleanup を呼び出していた事によります。
正しいコード
#include <winsock2.h> void simpleSend( const char* str ) { WSADATA wsaData; if( !WSAStartup(MAKEWORD(2,0), &wsaData) ) { // 送信処理 WSACleanup(); } return 0; }このように、WSAStartup に失敗したら、WSACleanup を呼び出さないようにする事が重要です。
0 件のコメント:
コメントを投稿