我有一个Dllmain,当线程连接到此DLL时,它会分配线程本地存储。代码如下:

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;
    ...

}
我知道,根据Microsoft文档,对于主线程,没有输入DLL_thread_ATTACH。但是,上面的代码起作用了。我在用VC2005。当我进入调试器时,我看到在它进入DLL_THREAD_ATTACH case之后,ul_reason_for_call=1!怎么会这样?如果我在DLL进程附加块的末尾添加'break',DLL将无法工作。
怎么会这样?

最佳答案

如果我正确理解您的意思,您会想知道为什么在输入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;
...

10-08 11:58