2011-01-21 68 views
5

我試圖延遲爲C++/CLI應用程序加載我的依賴.dll,以便我可以測試它們的存在並警告用戶,而不是僅僅崩潰。如何延遲在C++ - CLI(.net)應用程序中加載.dll文件?

我試着添加DLL文件MyProject->屬性 - > ConfigurationProperties->連接器 - >輸入 - >延遲加載的DLL ...但只是給我一個警告,它不是引用它們:

5> LINK:警告LNK4199:/DELAYLOAD:Util.dll忽略;無論從Util.dll

發現如果我刪除一個.dll並運行它崩潰,並希望將信息發送到微軟關於失蹤的.dll的應用程序,它看起來像它仍然在嘗試通過加載所有的模塊進口因此啓動和適應。

僅供參考,我的應用程序啓動時看起來是這樣的:

using namespace System; 
using namespace System::Collections::ObjectModel; 
using namespace Microsoft::Win32; 

[STAThreadAttribute] 
int main(array<System::String ^> ^args) 
{ 
    try 
    { 
     // Enabling Windows XP visual effects before any controls are created 
     Application::EnableVisualStyles(); 
     Application::SetCompatibleTextRenderingDefault(false); 

     // First make sure we have all the .dlls we need 
     ArrayList^ missingDlls = gcnew ArrayList(); 
     Assembly^ assembly = Assembly::GetEntryAssembly(); 
     array<System::Reflection::AssemblyName^>^ referencedAssemblies = assembly->GetReferencedAssemblies(); 
     for each(System::Reflection::AssemblyName^ referencedAssemblyName in referencedAssemblies) 
     { 
      try 
      { 
       Assembly^ a = assembly->Load(referencedAssemblyName); 
       if(a == nullptr) 
       { 
        missingDlls->Add(referencedAssemblyName->Name); 
       } 
      } 
      catch(System::Exception^ e) 
      { 
       MessageBox::Show("Error loading "+referencedAssemblyName->Name); 
      } 
     } 

     ... 

回答

7

鏈接器的/ DELAYLOAD選項只適用於含有編譯爲機器碼函數的DLL。鏈接器已經告訴你,你沒有任何。

這裏可能的情況是您的DLL實際上包含IL而不是機器代碼。當你使用/ clr編譯源代碼並且沒有使用#pragma設法關閉IL代時會發生這種情況。 IL代碼需要通過抖動轉換爲機器代碼。

只要抖動需要程序集元數據中的類型信息以生成機器代碼,您的DLL就會動態加載,與/ delayload相同。爲了避免依賴於DLL,你必須仔細製作你的代碼,這樣抖動永遠不需要從你的程序集中加載類型。這是一個與避免執行延遲加載函數的不同的問題。異常的InnerException堆棧跟蹤應該給你一個強烈的提示,如何發生。

+0

「IL」代表什麼?我懷疑這可能是比它值得的更多的努力,從你所說的話,它可能是。 – 2011-01-21 16:09:04