2010-03-08 29 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