我有一个应该转换为库的应用程序。我只复制了项目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都会冻结(即使在这种情况下没有任何内容)。
什么是释放所有应用程序内容的正确方法?
答案 0 :(得分:9)
你在DLL程序中执行太多。
在加载DLL时,操作系统获取加载程序锁。这可以防止同时加载任何其他库。如果调用尚未加载的库中的函数,则会触发尝试加载该库。由于您仍在加载程序锁定内部,因此其他库在尝试获取锁定时会阻塞,并且您会遇到死锁。类似的规则适用于卸货。
您应该在DllMain函数中执行绝对最小值以使您的库加载或卸载。将其他所有内容保留为DLL主机在加载完成后或在卸载开始之前可以调用的单独函数。在您的情况下,最小值可能什么都没有。
答案 1 :(得分:0)
好的,我很清楚你对dll锁的总结,我把嵌入式应用程序构造函数/析构函数放在一些标准的导出dll例程中,所以不再有DllMain。然而,调用freelibrary仍然显示出僵局。我的dll由另一个dll实例化,它本身在可执行文件中实例化。也许锁是在流程层次结构的较低层引入的。