2012-01-10 62 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

相關問題