问题是由这个帖子而引起的http://community.csdn.net/Expert/topic/3813/3813006.xml?temp=.4357874你一直说是多线程共享支持,在网上有一个关于DLL的初始化和释放的例子,大致内容如下:library TestDLL;procedure MyDLLHandler(Reason: integer);
begin
 case Reason of
  DLL_Process_Attach: //整个DLL的初始化代码
  DLL_Process_Detach: //整个DLL的善後程序
  DLL_Thread_Attach: //当主叫端开始一个Thread时
  DLL_Thread_Detach: //当主叫端终止一个Thread时
 end;
end;begin
 DLLProc := @MyDLLHandler;
 MyDLLHandle(DLL_Process_Attach);
end.
可是我调用从来没有发生过DLL_Thread_Attach 和 DLL_Thread_Detach 。
怎样才能触发呢?
给个例子吧!这方面我不熟啦!

解决方案 »

  1.   

    我怎么看不明白阿?library TestDLL;procedure MyDLLHandler(Reason: integer);
    begin
     case Reason of
      DLL_Process_Attach: //整个DLL的初始化代码
      DLL_Process_Detach: //整个DLL的善後程序
      DLL_Thread_Attach: //当主叫端开始一个Thread时
      DLL_Thread_Detach: //当主叫端终止一个Thread时
     end;
    end;begin
     DLLProc := @MyDLLHandler;
     MyDLLHandle(DLL_Process_Attach);//这里传进个常量?那不是总是执行初始化那段吗?
    end.
      

  2.   

    没发生就没发生了,没所谓的
    以普Proc_att就足够用了http://lysoft.7u7.net
      

  3.   

    //先载入DLL,然后这个进程创建线程后,那个DLL会有DLL_Thread_Attach发生。。
    //DLL_Thread_Detach在有些情况下则不一定会发生。。
    //下面是我刚测试用的代码。
    library TestDLL;uses
      SysUtils,
      Classes,windows;{$R *.res}
    const
      DLL_PROCESS_DETACH = 0;
      DLL_PROCESS_ATTACH = 1;
      DLL_THREAD_ATTACH  = 2;
      DLL_THREAD_DETACH  = 3;procedure WriteLog(s:string);
    var
      logname:string;
      fo:TFileStream;
      tmp:string;
      threadid:Cardinal;
    begin
      logname:='d:\testdll.log';
      if FileExists(logname) then
      begin
        fo:=TFileStream.Create(logname,fmOpenWrite);
        fo.Position:=fo.Size;
      end
      else
      begin
        fo:=TFileStream.Create(logname,fmCreate);
      end;
      try
        threadid:=GetCurrentThreadId;
        tmp:=DateTimeToStr(now)+'(threadid:'+IntToStr(threadid)+')"'+s+'"'#13#10;
        fo.Write(pchar(tmp)^,length(tmp));
      finally
        fo.Free;
      end;
    end;procedure DoProcessAttach;
    begin
      WriteLog('ProcessAttach');
    end;
    procedure DoProcessDetach;
    begin
      WriteLog('ProcessDetach');
    end;
    procedure DoThreadAttach;
    begin
      WriteLog('ThreadAttach');
    end;
    procedure DoThreadDetach;
    begin
      WriteLog('ThreadDetach');
    end;procedure MyDLLHandler(Reason: integer);
    begin
      case Reason of
        DLL_PROCESS_ATTACH: DoProcessAttach;//整个DLL的初始化代码
        DLL_PROCESS_DETACH: DoProcessDetach;//整个DLL的善後程序
        DLL_THREAD_ATTACH:  DoThreadAttach;//当主叫端开始一个Thread时
        DLL_THREAD_DETACH:  DoThreadDetach;//当主叫端终止一个Thread时
      end;
    end;begin
      DLLProc := @MyDLLHandler;
      MyDLLHandler(DLL_Process_Attach);
    end.
      

  4.   

    //MAIN程序比较简单。。就是一个FORM上面放了三个按钮
    //BUTTON1按下,主线程载入DLL。。
    //BUTTON2按下,主线程释放DLL。。
    //BUTTON3按下,创建一个线程,自生自灭,不做什么事。//当先按下BUTTON1,然后按下BUTTON3。就可以去看看日志文件了。。
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;  TTestThread=class(TThread)
      protected
        procedure Execute;override;
      end;
    var
      Form1: TForm1;
    implementation
    {$R *.dfm}
    var
      dllhandle:THandle;procedure TForm1.Button1Click(Sender: TObject);
    begin
      dllhandle:=LoadLibrary('TestDll.dll');
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      FreeLibrary(dllhandle);
    end;procedure TTestThread.Execute;
    begin
      FreeOnTerminate:=true;
    end;procedure TForm1.Button3Click(Sender: TObject);
    begin
      TTestThread.Create(false);
    end;
      

  5.   

    //呵,这是从MS网站上找到的文档关于那两个东西触发的条件。。Additional care must be taken when relying on DllMain being called with DLL_THREAD_ATTACH and DLL_THREAD_DETACH because of the following conditions: • When a thread is created in a process, the system calls DllMain with a value of DLL_THREAD_ATTACH for each of the DLLs mapped into into the process. However, if a process has several threads running in it when a new DLL is mapped into it, DllMain isn't called with a DLL_THREAD_ATTACH value for any of the existing threads.  • DllMain is not called with a value DLL_THREAD_ATTACH for the process's primary thread.  • On thread termination (by a call to ExitThread), DllMain is called with a value of DLL_THREAD_DETACH for each of the DLLs. DllMain is not called with DLL_THREAD_DETACH for any thread unless a thread terminates by calling ExitThread.  • If a thread terminates due to a call to TerminateThread, DllMain isn't called with a value DLL_THREAD_DETACH.  • It is possible for a thread in a process to call LoadLibrary to load a DLL causing a call to DllMain with DLL_PROCESS_ATTACH, and then on thread termination, cause a call to dllMain with DLL_THREAD_DETACH without ever calling DLL_THREAD_ATTACH. It is therefore best that the thread that calls LoadLibrary also call FreeLibrary.  
      

  6.   

    哦还有这种用法……又上了一课不过哈欠阿那个DLL_THREAD_ATTACH确实有时候不太好用的说……
      

  7.   

    看完了先等等  ad 日志文件写的什么 我这里没有delphi  看ms的解释应该没有DLL_THREAD_DETACH是吧
      

  8.   

    我看MSDN,上面是这样说的……Entry-Point Function DefinitionThe DLL entry-point function must be declared with the standard-call calling convention. If the DLL entry point is not declared correctly, the DLL is not loaded, and the system displays a message indicating that the DLL entry point must be declared with WINAPI.Windows Me/98/95:  If the DLL entry point is not declared correctly, the DLL is not loaded and the system displays a message titled "Error starting program," which instructs the user to check the file to determine the problem.
    In the body of the function, you may handle any combination of the following scenarios in which the DLL entry point has been called:
    A process loads the DLL (DLL_PROCESS_ATTACH). 
    The current process creates a new thread (DLL_THREAD_ATTACH). 
    A thread exits normally (DLL_THREAD_DETACH). 
    A process unloads the DLL (DLL_PROCESS_DETACH). The entry-point function should perform only simple initialization tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, the entry-point function must not call the FreeLibrary function (or a function that calls FreeLibrary) during process termination, because this can result in a DLL being used after the system has executed its termination code.Because Kernel32.dll is guaranteed to be loaded in the process address space when the entry-point function is called, calling functions in Kernel32.dll does not result in the DLL being used before its initialization code has been executed. Therefore, the entry-point function can create synchronization objects such as critical sections and mutexes, and use TLS, because these functions are located in Kernel32.dll. It is not safe to call the registry functions, for example, because they are located in Advapi32.dll.Calling other functions may result in problems that are difficult to diagnose. For example, calling User, Shell, and COM functions can cause access violation errors, because some functions in their DLLs call LoadLibrary to load other system components. Conversely, calling those functions during termination can cause access violation errors because the corresponding component may already have been unloaded or uninitialized.
      

  9.   

    我试了一头汗却始终显示一种结果……
    经过我的反复测试,发现,其实还是这里调用的……library TestDLL;procedure MyDLLHandler(Reason: integer);
    begin
     case Reason of
      DLL_Process_Attach: //整个DLL的初始化代码
      DLL_Process_Detach: //整个DLL的善後程序
      DLL_Thread_Attach: //当主叫端开始一个Thread时
      DLL_Thread_Detach: //当主叫端终止一个Thread时
     end;
    end;begin
     DLLProc := @MyDLLHandler;
     MyDLLHandle(DLL_Process_Attach);//就是这里!
    end.
    你写啥就是啥了-_-!晕死我了,呵呵先下班,回去接着试去……
      

  10.   

    晕死了今天跟哈欠试了一上午代码没问题但是在我机器上编译的就不能用在哈欠机器上编译的能用……百思不解ing... ...去他的,暂时不考虑了这种用法记住了,等用到的时候再说吧……
      

  11.   

    哈哈,怎么开始研究这个呢?讨论这么多还不如看看Aminigoo的Delphi源码分析呢。有关DLL的问题,他写的很详细的。
      

  12.   

    2005-03-03 11:44:51(threadid:704)"ProcessAttach"
    2005-03-03 11:44:53(threadid:2060)"ThreadAttach"
    2005-03-03 11:44:53(threadid:2060)"ThreadDetach"
    2005-03-03 11:44:54(threadid:704)"ProcessDetach"
      

  13.   

    to reallike:
      不是研究,只是以前这个用法不知道,正好在这看见了,我就顺便试试,学习学习,
    没想到一试试出个我的delphi编译有问题……  真TMD郁闷阿
      

  14.   

    记得前两天 你说你们的delphi到期了 不是去申请了吗难道这玩意到期了 还限制Debug不成