我写了一个win32 dynamic link library,大体如下:
int a=1;//变量a因为在fun1和fun2函数中都要用到,所以在函数体外初始化
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
    switch(ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
    }
    return TRUE;
}
fun1()
{
......
}
fun2()
{
......
}第一个线程调用dll时,将a值由1改为0。第二个线程调用dll时a的初始值就为0了。我希望第二个线程调用dll时a的初始值仍然为1,应该如何做?是不是a初始化的地方不对?高手救我!

解决方案 »

  1.   

    使用TLS技术就可以很容易的解决这个问题
    #include <windows.h>static DWORD dwTlsIndex; // address of shared memory
     
    // DllMain() is the entry-point function for this DLL. 
     
    BOOL WINAPI DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)   

        LPVOID lpvData; 
        BOOL fIgnore; 
     
        switch (ul_reason_for_call) 
        { 
            case DLL_PROCESS_ATTACH: 
     
                // Allocate a TLS index.
                if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) 
                    return FALSE; 
     
            // The attached process creates a new thread. 
     
            case DLL_THREAD_ATTACH:             lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(int) ); 
                memset( lpvData, 0, sizeof(int) );
                if (lpvData != NULL) 
                    fIgnore = TlsSetValue(dwTlsIndex, lpvData); 
     
                break; 
     
            // The thread of the attached process terminates.
            case DLL_THREAD_DETACH: 
     
                // Release the allocated memory for this thread.
     
                lpvData = TlsGetValue(dwTlsIndex); 
                if (lpvData != NULL) 
                    LocalFree((HLOCAL) lpvData); 
     
                break; 
     
            // DLL unload due to process termination or FreeLibrary. 
            case DLL_PROCESS_DETACH: 
     
                // Release the allocated memory for this thread.
                lpvData = TlsGetValue(dwTlsIndex); 
                if (lpvData != NULL) 
                    LocalFree((HLOCAL) lpvData); 
     
                // Release the TLS index.
     
                TlsFree(dwTlsIndex); 
                break; 
     
            default: 
                break; 
        } 
     
        return TRUE; 
    }在fun1,fun2中这么用:
    fun1()
    {
       LPVOID lpvData;    lpvData = TlsGetValue(dwTlsIndex);    // If NULL, allocate memory for the TLS slot for this thread
       if (lpvData == NULL)
       {
          lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(int) ); 
          if (lpvData == NULL) 
             return FALSE;
          if (!TlsSetValue(dwTlsIndex, lpvData))
             return FALSE;
       }   int * pData = (int *) lpvData; // Cast to my data type.   *pData = 0;//怎么做都行了}
      

  2.   

    补充: 在申请了变量的内存之后,对其初始化。如 DLL_THREAD_ATTACH里面
    lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(int) );
                memset( lpvData, 0, sizeof(int) );  //初始化为0,当然可以初始化成自己想要的值。在导出函数fun1 中增加 if (lpvData == NULL)  这个判断只是 为了代码的逻辑更加严密。
      

  3.   

    liyinlei,我按照你所说的试了一下,
    fun1() 

      LPVOID lpvData;   lpvData = TlsGetValue(dwTlsIndex); 
    ......
    }
    fun2() 

      LPVOID lpvData;   lpvData = TlsGetValue(dwTlsIndex); 
    ......
    }
    按照我上面的这种写法是不是fun1和fun2里的lpvData指针是同一个指针?
    可是我调试的时候为什么它们的地址不一样呢?我希望的是变量在fun1里更改之后,在fun2中该变量的值也同样更改。
      

  4.   

    你的需求有点不明白:
    那个int a是线程内共享的还是线程间共享的?
    我的意思是,你的要求:
    1、线程A初次访问a时a==0;
    2、A对a进行操作(a值不定)
    3、线程B初次访问a时a==0;
    4、接下来,B如果再访问a,你是想使用此时线程A中的值呢,还是怎样?
      

  5.   

    楼上的,我希望int a是线程内共享。线程A和线程B对整个Dll的访问是互不干扰的
      

  6.   

    楼上的各位,不好意思啊,之前我没有理解正确误导你们了! 
    我的fun1和fun2不在同一个线程函数里面。事实上我的要求是这样的, 
    我写了一个类Class,大体如下: 
    DWORD Class::fun()    //任意一个函数 

    fun1() 
    ...... 

    DWORD Class:Thread_fun()  //线程函数 

    fun2() 
    ...... 

    这个类Clss对应多个实例,我希望每个实例调用dll互不干扰。有什么办法可以实现呢? 
    谢谢!
      

  7.   

    线程内多个函数使用的变量,不用放到DLL的全局共享中去,直接在进程中生成,作为参数传给线程,这样就能解决问题了。
      

  8.   

    在VC中可以直接用__declspec(thread) int a=1;解决
      

  9.   

    我给你的例子里是 线程间互不干扰
    如果是同一个线程进入fun1和fun2,他们拿到的指针是同一个。