防止Delphi MDI应用程序在外部DLL中创建TApplication

时间:2012-01-10 14:20:46

标签: multithreading delphi synchronization delphi-xe2 vcl

这是一个问题(剩下的就是你可以告诉我,我做错了)

有什么方法可以确保第一个要运行的二进制文件(即我的可执行文件)是第一个初始化vcl.controls.pas吗?


我问this question a few months ago,我想出了如何在那里修复它并且同步再次工作只是为Delphi 2009而膨胀。

现在我们已经有了Delphi XE2,同样的症状正在发生。 TThread.Synchronize锁定,直到系统空闲或您将鼠标移动到活动表单上,导致程序超速。我可以在Delphi 2009中重新创建这个问题,因为我很幸运,发现源是一个非迂回链接的DLL,但我不相信这是XE2的情况。我不知道为什么XE2决定以不同于Delphi 7或2009的方式初始化代码,但根据我在另一个问题上的答案,TThread没有真正改变,所以它必须在其他地方。

好吧,我一直在逐步完成我的主MDI应用程序的初始化,它似乎在链接的DLL中调用TApplication.Create(在VCL.Controls.pas的初始化中发生)。我不能说我理解为什么这是一个问题,因为我使用相同的运行时包(VCL,RTL等)构建所有内容。

2 个答案:

答案 0 :(得分:2)

我们遇到了您描述的相同问题(尽管在C ++ Builder中)。似乎有三种可能的解决方案。

1)从DLL中删除所有VCL依赖项。这是我公司最终的目标,但短期内建议可能不是很有用。

2)使用包而不是DLL。这是我们从Borland的支持(很久以前)获得的官方答案。显然,如果你创建一个包(BPL)而不是DLL,它可以更好地搞清楚VCL的初始化。

3)我不知道这第三个解决方案潜藏着什么隐藏的问题,因为它非常糟糕,但是我现在正在将我们的系统应用创可贴,直到我们能够从我们的DLL中获取VCL (似乎可以工作)。

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    delete Application;
    Application = new TApplication(NULL);

但我必须承认,这让我有点紧张(这让我觉得有点脏)。

我确信您可以将其转换为Pascal,这个想法是销毁由DLL创建并分配给Application全局变量的原始TApplication对象。然后在可执行文件TApplication中创建自己的WinMain对象,并将其分配给全局Application变量。只要在你有机会扔掉之前没有任何东西存储了指向原始TApplication对象的指针,它似乎应该没问题。

答案 1 :(得分:1)

根据你在评论中所说的内容,我想我明白这里发生了什么...如果你使用external从主exe进入DLL的入口点,它们被加载程序启动时的操作系统。这会使事情变得复杂很多,因为BPL在运行时加载(使用LoadLibrary())很好。

因此,在EXE有时间进行初始化之前,您的DLL会将运行时BPL分别加载到EXE。