2010-03-08 66 views
0

我有一個Dllmain分配線程本地存儲當一個線程連接到此DLL。代碼如下:開關/案件沒有中斷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。當我進入調試器時,我看到在它進入DLL_THREAD_ATTACH的情況下,當ul_reason_for_call = 1!這怎麼可能發生?如果我在DLL_PROCESS_ATTACH塊的末尾添加了「break」,則DLL無法工作。

這是怎麼發生的?

回答

8

如果我正確理解你,你想知道爲什麼在進入DLL_PROCESS_ATTACH的情況下,執行繼續在DLL_THREAD_ATTACH的情況下,而不是在switch的結束之後。

此行爲被稱爲「fall through」,它是標準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++經驗,但我從來沒有寫過這樣的結論。我總是在每個分支或多個案例中分攤(共享相同的代碼塊)。第一次看起來很奇怪。 – cuteCAT 2010-03-08 20:03:34

+0

@Sherwood Hu - 是的,乍看起來很奇怪:-)我意識到我的措辭可能讓你覺得有辱人格,所以我重新編寫了它。現在您對您的問題得到了滿意的答案,請問您是否符合SO常規?謝謝。 – 2010-03-08 20:21:59

+0

更好的做法是將'DLL_THREAD_ATTACH'代碼放在它自己的函數中,並從'DLL_PROCESS_ATTACH'和'DLL_THREAD_ATTACH'中調用它,同時添加「missing」'break' – 2016-06-20 09:40:38

1

您是否瞭解switch語句的工作原理?如果你不把休息的情況下結束,那麼代碼只是延續到下一情況:

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

都打印3和4