dll을 제작하였고, DllMain에 다음과 같이 coding되어 있습니다.
BOOL APIENTRY DllMain( HANDLE hModule, DWORD l_reason_for_call, LPVOID lpReserved)
{
switch(ul_reason_for_call){
case DLL_PROCESS_ATTACH:
MyFunc();
InitializeCriticalSection(&g_cs);
break;
case DLL_PROCESS_DETACH:
MyFunc();
DeleteCriticalSection(&g_cs);
break;
case DLL_THREAD_ATTACH:
MyFunc();
break;
case DLL_THREAD_DETACH:
MyFunc();
break;
}
return TRUE;
}
dll을 호출하는 Main Application에서 쓰레드가 생성되거나 없어질 때 DLL_THREAD_ATTACH, DLL_THREAD_DETACH 부분이 실행되게 됩니다.
문제는 이 수행이 OS마다 다르다는 것입니다.
예를 들어 Main Application에서 sndPlaySound('test.wav', SND_ASYNC) 를 호출하게 되면 내부적으로 쓰레드를 생성하게 되고, 따라서 소스의 DLL_THREAD_ATTACH부분이 수행되어야 하는데 Windows 2000에서는 수행이 되지만 Windows98에서는 수행이 되지 않는군요.
OS마다 다르게 돌아가는 것 같은데, 혹시 저와 비슷한 경우를 접해 본 분이 있는지요.
DllMain 안에서는 CriticalSection 을 사용하면 안됩니다. 락걸립니다.
DLL 이라는게 서로서로 PE (DLL들 같은) 파일들을 연결고리로 물고
있는 바이너리 파일이기 때문에 DllMain 에다가 크리티컬 섹션을 사용하면
위의 해당 DLL 파일이 로딩되면서 같이 로딩하는 또 다른 제3의 DLL
파일들이 위의 DLL 파일을 연계해서 다시 로딩하는 경우가 생기므로
크로교차 참고로 락이 걸립니다. 그렇기 때문에 DllMain 안에서는 크리티컬
섹션을 사용해서 락걸면 안됩니다. 작동된다 할지라도.. 잠재적으로 발견하기
어려운 크리티컬한 버그를 만들수 있음..