2011-01-21 67 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