2012-01-10 60 views
3

这是一个问题(剩下的只是所以你可以告诉我,我做的全部都是错的)防止Delphi MDI应用程序在外部DLL中创建TApplication

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


我问this question a few months ago和我想出如何到那里解决它,并同步再次合作只是膨胀了2009年德尔福

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

那么,我一直在通过我的主MDI应用程序的初始化,它似乎在链接的DLL内调用TApplication.Create(发生在VCL.Controls.pas的初始化中)。我不能说我明白为什么这是一个问题,因为我使用相同的运行时软件包(VCL,RTL等)构建了所有的东西。

+0

在我看来,该DLL没有使用运行时软件包...当你使用运行时软件包时,应该只有一个引用到所有VCL的VCL。 – Nat 2012-01-12 00:29:06

+0

除非有一些隐藏的.dproj奇怪,我可以确认每个DLL都使用确切的保存运行时软件包,包括VCL。实际上,我通过将有问题的DLL的'external'调用转换为调用'loadlibrary'和'getprocaddress'的delphi函数来解决这个问题。 – 2012-01-12 14:08:41

回答

1

根据你在评论中所说的话,我想我理解这里发生了什么......如果你使用external作为从主exe文件进入DLL的入口点,它们将被OS加载程序启动。这会使事情变得复杂,因为运行时(在使用LoadLibrary()之后)BPL被加载得很好。

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

+0

是的,那正是发生的事情,我想知道的是,如果有什么方法可以纠正这种情况的话。看起来奇怪的是,编译器不能以预定义的方式初始化单元和DLL的方式来解释事物。最令人讨厌的部分是它在Delphi 7中运行良好。然后,我不得不在Delphi 2009中进行调试和修复。然后,使用完全相同的代码,我必须在Delphi XE2中进行调试和修复。 – 2012-01-13 14:23:24

2

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

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

2)使用包而不是DLL。这是我们从Borland支持(很久以前)得到的官方答案。显然,如果你创建一个包(BPL)而不是一个DLL,它可以做一个更好的工作来搞清楚VCL初始化。 3)我不知道这个第三种解决方案隐藏着什么隐藏的问题,因为这是非常黑客,但这里是我目前如何在我们的系统上使用创可贴,直到我们能够将VCL从我们的设备中取出DLLs(并且它似乎工作)。

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

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

这个想法,我相信你可以把它翻译成Pascal,是破坏DLL创建的原始TApplication对象,它被分配到Application全局变量。然后在可执行文件WinMain中创建自己的TApplication对象,并将其分配给全局Application变量。只要在得到机会扔掉它之前没有存储指向原始TApplication对象的指针,它似乎应该没问题。

+0

我们通过将所有外部引用的VCL启用的DLL设置为['delayed'](http://www.drbob42.com/examines/examinC1.htm)来解决它,它基本上将它们全部转换为动态链接的DLL,但是第3你的选择非常非常有趣,非常非常可怕。 – 2012-09-26 21:31:34

相关问题