自作DLL内でMFCソケットを利用する場合のメモ。

自作DLL内でMFCソケットを利用する場合、以下の点に注意する必要がある。
http://support.microsoft.com/kb/196836/

このKBでは、DLLのCWinApp::ExitInstance()内でMFCソケット関数を呼び出すとエラーになることがあるよと言っている。
だが、ExitInstance()内だけではなくCWinAppのデストラクタでも該当し、DLL内で確保したCAsyncSocket(CSocketもかな)、またはその派生クラスのオブジェクトをdeleteするようなコードを記述している場合、ソケットがリスニング中等ではエラーになりデバッグ版だとアサーションが発生する。
ということは、DLL内のCWinApp派生オブジェクトのデストラクタやExitInstanceでCAsyncSocket派生クラスをdeleteする手段がなくなるため、DLL内で自律的にMFCソケットをdeleteできない。
このため、アプリが終了する時に必ずDLLの終了処理用の関数を呼び出して貰うしか手がなくなる。

具体的にはCAsyncSocketのデストラクタでClose()が呼び出され、さらにclosesocket()が呼び出された場合にエラーとなりVERIFY(SOCKET_ERROR != closesocket(m_hSocket));でアサーションが発生。GetLastError()で10093が返る。
10093はここ(http://www.geocities.jp/fjtkt/download/sample/SysError20030914.html)によるとアプリケーションが WSAStartup を呼び出していないか、または WSAStartup が失敗しました。とのことなので、たぶんwsock32.dllが先に終了してるんだろう。
リリース版ならアサーションでないし、無視しても問題ない気もするが・・・んー、なんだかなぁ。