我觉得应该是DLL全局变量的长,但最近做的东西又好象不是这么回事,想请教下。主要是怕DLL线程生存周期更长的话,会去操作已经死亡的DLL全局变量,引发错误。

解决方案 »

  1.   

    线程你在DLL卸载时要结束,这样全局变量应该比线程长.
      

  2.   

    主要不了解DLL卸载时的善后顺序
      

  3.   

    线程是属于进程的,即使是在DLL内创建的,也可能在DLL卸载后还存在的。DLL就是一砣代码而已,作为一个模块,会在卸载时被强制一起清除的,只有它的全局变量和资源。
      

  4.   

    我做了个最简单模型,DLL里会启动的线程如:
    void threadInDll(PVOID pv)
    {
      while(TRUE)
      {
        Sleep(1000);
      }
    }动态加载DLL,启动该线程,卸载DLL,因为TRUE随DLL消亡,线程仍存在,报错。由此证明了DLL全局变量的生存周期跟DLL一样,但DLL创建的线程,生存期不随DLL卸载而消亡。
      

  5.   

    全局变量析构是在DLL_PROCESS_DETACH的时候,因而比线程的生存期长
      

  6.   


    你这个概念有点不对,TRUE是一个宏,是1,一个立即数,存在于代码中,不是全局变量。
    你报错是因为你的DLL被卸载后,这个函数的代码所处的地址空间也随之一起释放了,会产生非法访问错误。
    你在你主模块里面定义线程函数,然后传进DLL让DLL中的代码创建线程执行这个函数,在DLL卸载时就不会挂了。
      

  7.   

    如果是:
    全局变量BOOL x = TRUE;
    void threadInDll(PVOID pv)
    {
       while(x)
       {
         Sleep(1000);
       }
    }
    呢(先不讨论怎么改变,那样会展开新话题),这个应该符合主题吧,结果应该是报错,表明DLL创建的线程比DLL的全局变量生存周期长吧。
      

  8.   

    结果肯定报错的,DLL中的全局变量随DLL卸载销毁,地址空间被释放。如果threadInDll函数也是在DLL中的话,那就访问x的时候挂的,也可能访问指令时挂的。
    DLL创建的线程和主程序创建的线程没有任何区别,严格说拿线程和全局变量不能拿来作比较。
      

  9.   

    如果全局变量属于主程序 什么dllmain的?因该是全局变量堆栈先释放 主程序结束 线程因该是异常结束吧
      

  10.   

    因为线程的代码在dll的内存上。
    所以,在dll卸载前,线程必须被终止。如果卸载dll而线程仍然运行的话则必出错,因为线程所在的内存已经无效,cpu再取指必出错。
    全局变量在dll内存中,所以生存周期与dll一样长。所以时间顺序如下:
    (1) 线程终止
    (2) dll卸载,全局变量无效。
    全局变量生存周期》线程。但如果你new 一段内存,然后把线程代码copy到这段内存中,再开始线程的话,那就例外。
      

  11.   

    根本不是生存周期的问题...
    而是DLL退出时, DLL创建的一切资源必须先释放的, 引用DLL内部的任何资源也必须先释放的. 
    全局变量肯定是在DllMain运行完之后才会释放掉的
      

  12.   

    是指12楼说的new出来的代码吗,new是在系统堆栈上的吧,进程结束不影响里面的代码吧。
      

  13.   

    这里new用的堆是进程的用户地址空间中,进程结束时都会没的
    没有系统堆栈这个说法
      

  14.   

    哦,搞错了,还是进程用户空间内,内存泄露在进程结束后不存在了。现在又回到了怎么实现这个new内存然后copy线程代码进去然后启动线程的技术上来了。
      

  15.   

    new用的堆不是可执行的,如果有数据执行保护则不行
    你可以使用HeapCreate创建一个可执行的堆,然后用HeapAlloc在上面分配一块内存,然后把代码放在上面
      

  16.   

    楼上的,你们在讨论什么啊?难道在DLL中创建的线程,在DLL卸载时,不需要先将线程退出吗?为什么还会有谁的生命期更长这种讨论。
      

  17.   

    楼上的,你的概念就错了,线程在哪儿创建的根本没有影响,有影响的是线程所运行的代码、要访问的地址还存不存在,如果在DLL地址空间中被卸载了、不存在了,就会产生非法访问异常,程序挂掉。
      

  18.   

    主要看的书有限,没有能够看到DLL卸载前必须要把DLL创建的线程结束的编程原则,所以就有了题目所问。不过话说回来,不管有没有什么“标准编程原则”,实际应用中应该难免由DLL创建线程,如果线程时间难控制,那么卸载DLL前就只能强退线程了吗?也就是对DLL创建的线程在卸载DLL前如何善后的问题,请指教。
      

  19.   

    我有一个api hook的用到了这个,把你的邮箱发来我给你
      

  20.   

    DLLMAIN 里面有几个入口 CASE标志 加载\卸载 等最好结合起来