2010-03-08 2 views
0

스레드가이 DLL에 연결될 때 스레드 로컬 저장소를 할당하는 Dllmain이 있습니다. 아래 코드 :DllMain 내부의 중단없는 스위치/케이스

BOOL APIENTRY DllMain(HMODULE hModule, 
         DWORD ul_reason_for_call, 
         LPVOID lpReserved) 
{ 
    LPVOID lpvData; 
    BOOL fIgnore; 

    switch (ul_reason_for_call) 
    { 
    case DLL_PROCESS_ATTACH: 
     onProcessAttachDLL(); 
     // Allocate a TLS index. 
     if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) 
      return FALSE; 
     // how can it jump to next case??? 
    case DLL_THREAD_ATTACH: 
     // Initialize the TLS index for this thread. 
     lpvData = (LPVOID) LocalAlloc(LPTR, MAX_BUFFER_SIZE); 
     if (lpvData != NULL) 
      fIgnore = TlsSetValue(dwTlsIndex, lpvData); 
     break; 
    ... 

}

내가 메인 스레드를 들어, DLL_THREAD_ATTACH는 마이크로 소프트의 문서에 따라, 입력되지 않았 음을 알 수 있습니다. 그러나 위의 코드가 작동했습니다. VC2005를 사용하고 있습니다. 디버거를 입력했을 때 ul_reason_for_call = 1 일 때 DLL_THREAD_ATTACH가 입력 된 것을 보았습니다! 어떻게 그럴 수 있습니까? DLL_PROCESS_ATTACH 블록 끝에`break '를 추가하면 DLL이 작동하지 않습니다.

어떻게 이런 일이 발생할 수 있습니까?

답변

8

정확하게 이해하면 DLL_PROCESS_ATTACH 사례를 입력 한 후 switch 끝 부분 대신에 DLL_THREAD_ATTACH 사례에서 실행이 계속되는 이유가 궁금합니다.

이 동작을 "폴 스루"라고하며 표준 C입니다. 명시적인 break 문이 없으면 실행은 다음 case에서 계속됩니다.

처음으로 보는 프로그래머에게는 매우 직관력이 떨어지기 때문에 오해와 심지어는 버그의 지속적인 출처입니다. break이 의도적으로 또는 실수로 빠졌는지 항상 알 수는 없습니다.

switch (ul_reason_for_call) 
{ 
case DLL_PROCESS_ATTACH: 
    onProcessAttachDLL(); 
    // Allocate a TLS index. 
    if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) 
     return FALSE; 
    // fall through 
case DLL_THREAD_ATTACH: 
    // Initialize the TLS index for this thread. 
    lpvData = (LPVOID) LocalAlloc(LPTR, MAX_BUFFER_SIZE); 
    if (lpvData != NULL) 
     fIgnore = TlsSetValue(dwTlsIndex, lpvData); 
    break; 
... 
+0

감사합니다. 저는 C/C++로 다년간의 경험을 쌓았지만, 그런 construt을 쓰지 않았습니다. 나는 항상 각 분기 또는 여러 사례 (동일한 코드 블록 공유)에 휴식 시간을 넣습니다. 처음에는 이상하게 보입니다. – cuteCAT

+0

@Sherwood Hu - 예, 이상하게 보입니다 :-) 나는 내 말씨가 당신에게 타락한 것처럼 느껴졌을 것이라고 생각했다. 질문에 대한 만족스러운 답변을 얻었으니 SO 협약에 따라 동의 해 줄 것을 요청할 수 있습니까? 감사. –

+0

"DLL_THREAD_ATTACH"코드를 자신의 함수에 넣고'DLL_PROCESS_ATTACH'와'DLL_THREAD_ATTACH' 둘 다에서 호출하는 한편, "missing"'break' –

1

당신이 스위치 문이 작동하는 방법을 이해 하는가 : 그것은처럼,이 구조를 사용하는 경우, 따라서 댓글로 명시 적으로 표시하는 좋은 연습 간주됩니다? 이 사건의 끝에 휴식을 넣어하지 않는 경우, 다음의 코드는 다음의 경우에 계속 :

switch (3) 
{ 
case 3: 
    cout << "3"; 
case 4: 
    cout << "4"; 
} 

인쇄 모두 3과 4