将delphi win32应用程序转换为库和FreeLibrary冻结

时间:2010-06-26 22:45:00

标签: delphi dll

我有一个应该转换为库的应用程序。我只复制了项目dpr并更改了源文件:

library aLibrary;
  uses
  FastMM4, 
  Forms,
  SysUtils,
  Windows,
  Mainfrm in 'Mainfrm.pas' {Mainform};
{$R *.res}
Procedure DllMain(Reason: Integer);
Begin
  If Reason = DLL_PROCESS_ATTACH Then
    Begin
      Application.Initialize;
      Application.CreateForm(TMainForm, MainForm);
      ExitCode := 0;
    End;
  If Reason = DLL_PROCESS_DETACH Then
    Begin
      Application.Terminate;
      MainForm.Free;
    End;
End;
Begin
  DllProc := @DllMain;
  DllProc(DLL_PROCESS_ATTACH);
End.

正如您所看到的,我只是删除了与应用初始化相关的通常自动生成的代码行,并将它们放入DllMain过程中,将'program'关键字更改为'library'。 dll加载得很好,嵌入式程序也运行良好,但我无法在主机进程中设法释放它(FreeLibrary)。无论DLL_PROCESS_DETACH代码是什么,dll都会冻结(即使在这种情况下没有任何内容)。

什么是释放所有应用程序内容的正确方法?

2 个答案:

答案 0 :(得分:9)

你在DLL程序中执行太多

在加载DLL时,操作系统获取加载程序锁。这可以防止同时加载任何其他库。如果调用尚未加载的库中的函数,则会触发尝试加载该库。由于您仍在加载程序锁定内部,因此其他库在尝试获取锁定时会阻塞,并且您会遇到死锁。类似的规则适用于卸货。

您应该在DllMain函数中执行绝对最小值以使您的库加载或卸载。将其他所有内容保留为DLL主机在加载完成后或在卸载开始之前可以调用的单独函数。在您的情况下,最小值可能什么都没有

答案 1 :(得分:0)

好的,我很清楚你对dll锁的总结,我把嵌入式应用程序构造函数/析构函数放在一些标准的导出dll例程中,所以不再有DllMain。然而,调用freelibrary仍然显示出僵局。我的dll由另一个dll实例化,它本身在可执行文件中实例化。也许锁是在流程层次结构的较低层引入的。