【问题标题】:Prevent Delphi MDI application from creating TApplication in external DLL防止 Delphi MDI 应用程序在外部 DLL 中创建 TApplication
【发布时间】:2012-02-06 22:48:56
【问题描述】:

这就是问题(剩下的只是为了让你告诉我我做错了)

有什么方法可以确保要运行的第一个二进制文件(即我的可执行文件)是第一个初始化 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 等)构建所有东西。

【问题讨论】:

  • 在我看来,那个 DLL 没有使用运行时包...当您使用运行时包时,所有这些包中应该只有一个对 VCL 的引用。
  • 除非有一些隐藏的 .dproj 怪异之处,否则我可以确认每个 DLL 都使用精确的保存运行时包,包括 VCL。实际上,我确实通过将有问题的 DLL 的external 调用转换为调用loadlibrarygetprocaddress 的delphi 函数来解决这个问题。

标签: multithreading delphi synchronization delphi-xe2 vcl


【解决方案1】:

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

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

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

3) 我不知道这第三个解决方案潜伏着什么隐藏的问题,因为它是一个 hack,但这是我目前对我们的系统应用创可贴的方法,直到我们可以从我们的 DLL 中获取 VCL (而且它似乎有效)。

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

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

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

【讨论】:

  • 我们通过将所有外部引用的 VCL 启用的 DLL 设置为 'delayed' 来修复它,这基本上将它们全部转换为动态链接的 DLL,但是您的第三个选项非常非常有趣并且非常非常吓人。
【解决方案2】:

根据您在 cmets 中所说的话,我想我了解这里发生了什么...如果您使用 external 作为您从主 exe 进入 DLL 的入口点,它们将由操作系统加载在程序启动时。这会使事情变得非常复杂,因为 BPL 会在此之后由运行时加载(使用 LoadLibrary())。

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

【讨论】:

  • 是的,这正是正在发生的事情,我想知道是否有任何方法可以纠正它。编译器无法以预定义的方式初始化单元和 DLL 的方式来解释事物,这似乎很奇怪。最烦人的部分是它在 Delphi 7 中运行良好。然后我不得不在 Delphi 2009 中调试和修复它。然后,使用完全相同的代码,我不得不在 Delphi XE2 中调试和修复它。
猜你喜欢
  • 2023-03-26
  • 1970-01-01
  • 2013-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多