2011-01-21 13 views
5

Bir C++/CLI uygulaması için benim bağımlı .dlls yüklemeyi geciktirmeye çalışıyorum, böylece onların varlığını test edebilirim ve sadece çökmek yerine kullanıcıyı uyarıyorum.C++ - CLI (.net) uygulamasında yükleme .dlls'i nasıl geciktiririm?

Ben> MyProject-> Özellikler-> ConfigurationProperties-> bağlayıcı-> Girdi için Gecikme yüklenen DLL DLL ekleyerek denedim ... ama bu sadece bana bunları başvuran değil bir uyarı verir:

5 LINK: LNK4199 uyarısı: /DELAYLOAD:Util.dll yoksayıldı; Bir .dll silmek ve hala tüm modülleri yüklemek için çalışıyor gibi görünüyor bu yüzden çöker ve eksik .dll hakkında microsoft bilgi göndermek istediği uygulamayı çalıştırırsanız Util.dll

den bulunamadı ithalatı Başlangıç ​​ve sonuç olarak uygun.

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); 
      } 
     } 

     ... 

cevap

7

linker'ın/delayload seçeneği yalnızca yerli makine koduna derlenmiş işlevleri içeren DLL için çalışır:

Bilginize, benim app başlangıç ​​şuna benzer. Linker zaten size ait olmadığını söyledi.

Buradaki olası senaryo, DLL dosyanızın aslında makine kodu değil, IL içermesidir. Kaynak kodunu/clr ile birlikte derlediğinizde ve #pragma kullanılmadığında IL neslini kapatmayı başardınız. IL kodunun jitter tarafından makine koduna dönüştürülmesi gerekir.

DLL dosyanızın, makine kodu oluşturmak için derlemenin meta verilerden bilgi türüne sahip olması gerektiğinde, DLL dosyanız dinamik olarak/delayload ile aynı şekilde yüklenecektir. DLL'deki bağımlılığı önlemek için, kodunuzu dikkatli bir şekilde hazırlamanız gerekir, böylece jitter asla montajınızdan türler yüklemeye gerek duymaz. Gecikmeli bir işlev olan'u çalıştırmadan kaçınmasından farklı bir sorun. Özel durumun InnerException'ın yığın izlemesi, bunun nasıl gerçekleştiğine dair güçlü bir ipucu vermelidir.

+0

"IL" ne anlama geliyor? Şüpheliydim ki bu muhtemelen değerinden daha fazla çaba gösterecek ve söylediklerinden daha büyük bir çaba olacaktı. –

+0

Maalesef kendim istisnayı yakalama şansı bulamadım ve gördüğüm tek şey, hata raporunda Miscrosoft'un kendilerini göndermek istediği dış kısımlar. –

+1

IL == Orta Düzeyde,/clr ile derlediğinizde hangi kod çevrilir? Jitter bunu makine koduna çevirir. Bunun gibi işlenmeyen özel durumları günlüğe kaydetmek için AppDomain.CurrentDomain.UnhandledException öğesine abone olun. Bu yöntem, böyle bir derlemeden türler kullanıyorsa, Main() yönteminiz çalışmaya başlamadan önce teknik olarak yükseltilebilir. –

İlgili konular