我正忙於編寫一個爲主機應用程序提供多種功能的DLL。 該應用程序動態調用dll,在每次函數調用後加載並釋放它。德爾福動態Dll - 全局變量
我無法控制主機應用程序。我只能在dll內工作。 有沒有辦法讓內存中的某些變量保留下來,以便我可以在每個函數中重用它們?很明顯,當主機應用程序卸載dll時,全局可變數據就會被清除。 保存DLL文件聽起來非常混亂!
任何人都可以提出一種方法來分配一個變量,我可以保持全球?
謝謝
我正忙於編寫一個爲主機應用程序提供多種功能的DLL。 該應用程序動態調用dll,在每次函數調用後加載並釋放它。德爾福動態Dll - 全局變量
我無法控制主機應用程序。我只能在dll內工作。 有沒有辦法讓內存中的某些變量保留下來,以便我可以在每個函數中重用它們?很明顯,當主機應用程序卸載dll時,全局可變數據就會被清除。 保存DLL文件聽起來非常混亂!
任何人都可以提出一種方法來分配一個變量,我可以保持全球?
謝謝
我認爲你在這裏有兩個主要選項。
報價2版本的功能,你現在有一個,加上另一個地方,他們在緩衝區(記錄,等等),你可以讀取以前的狀態,當然更新狀態爲通過。稱這是函數的高性能版本。他們會想要使用它。
保存喜歡你的狀態會一個cookie(那基本上它是什麼)在文件中的某個地方。
選項1將需要修改主機應用程序,但將是引人注目的主機應用程序開發人員採取的,選項2優點將不需要改變到主機應用程序,但不會像高性能的。
我不會親自傾向於開始擺弄引用計數,想必主機應用程序正在卸載是有原因的,如果我是主機應用開發,這將激怒了我。
謝謝 - 我認爲這是最好的選擇。 我寧願保存到文件並採取性能比風險而不是擺弄dll引用。也許主機應用程序開發人員將繼續提供高性能版本 – Crudler 2009-06-26 12:30:27
最好的方法是使用包含「全局變量」的類。您實例化一個對象並將其作爲參數提供給dll函數。但這不會幫助你,因爲你無法更改調用應用程序。
如果你必須保持全局數據在DLL中,一個解決方案是將它們寫入文件。但這對性能造成嚴重影響。
如果我是你,我會的全局變量的值保存到一個文件時,該dll被釋放,當它被初始化加載它們。我沒有理由保存磁盤上的DLL的內存轉儲。
警告,骯髒的黑客:
您可以加載自己。
每次調用LoadLibrary
遞增引用計數器,FreeLibrary
遞減它。只有當計數器達到零時,DLL纔會被卸載。
因此,如果第一次你的DLL被加載時,你又把您的書架,從而增加引用計數器。如果調用應用程序調用FreeLibrary
引用計數器遞減,但該DLL不會被卸載。
編輯:正如mghi指出,如果進程終止,DLL是否會被卸載,引用計數是否爲零。
如果你有大量的全局數據要共享,另一個解決方案是創建一個windows服務來「緩存」狀態數據。您還需要實現某種跨越進程邊界的IPC,例如內存映射文件,郵箱,COM(本例爲單實例),TCP/IP等。您可能會發現這種開銷不僅僅是將狀態寫入文件,這就是爲什麼我只會在狀態數據量過多時才推薦這種方法,或者只會在每個請求的整個部分處理這些數據進入你的dll。
對於COM方法,除了請求(並保持)將用於維護狀態的com對象的實例之外,服務不必做太多的事情。由於它是一個單實例com對象,因此所有請求都將發送給同一個實例,從而允許您在請求之間保存狀態。對該對象的請求將被序列化,因此,如果您有多個客戶端同時在同一臺計算機上請求數據,則這可能是性能問題。
當DLL被釋放時將值寫入註冊表,並且在加載DLL時從註冊表讀取值。當讀取發現沒有設置密鑰時,不要忘記提供默認值。
-Al。
我同意之前關於全球狀態信息危險的評論,儘管我可以想象它可能是需要的。
我提出DR的骯髒的黑客更清潔的版本不具有作爲永久像skamradt的回答的缺點:
一個非常小的應用程序:
它沒有外觀無論如何,它讓自己從顯示在任務欄上。
任務#1:加載DLL
任務#2:把它的命令行,運行它,並等待它終止。
任務#3:卸載DLL
任務#4:退出。
安裝程序:
它找到快捷方式(多個)到主應用程序,並修改它們所以小應用程序運行時,原始位置的快捷指向變成第一參數。
結果:只有主應用程序正在運行,DLL纔會保留在內存中,但每次程序轉儲時它都不會被卸載。
這也可能是有益的
option 1:
創建握着你的頁面文件支持的變量共享內存區 - 如果你能打開共享內存區,你的DLL以前加載(假設「私人「共享內存名稱,可能名稱與process_id_yourdllname類似) - 如果您無法打開它,那麼您首次創建並初始化它。如果你創建了它,那麼你不用去刪除它 - 但是如果你打開它,你會在卸載時關閉它。我相信當應用程序關閉時該區域將被釋放,因爲沒有其他應用程序應該處理這個特定的「私有」共享內存區域。
option 2:
創建第二個。只存在用於管理全局變量的dll。你的DLL A可以加載該DLL B,而不是釋放它,放入DLL B無論你需要管理全局變量。當應用程序消失時它應該消失,我認爲你可能不需要關心(可能是無用的)引用計數(因爲你不會卸載dll B)。
您的設計很糟糕,原因很多。你有沒有想過多個主機應用程序(快速用戶切換,在終端服務器下使用)或主機應用程序從多個線程調用DLL函數的可能性?不惜一切代價儘量避免全局/共享狀態。 – mghie 2009-06-25 09:45:47