How do I delay loading .dlls in a C++-CLI (.net) application?
I'm trying to delay loading my dependent .dlls for a C++/CLI application so that I can test for their existence and warn the user instead of just crashing out.
I've tried adding the dlls to MyProject->Properties->ConfigurationProperties->Linker->Input->Delay Loaded DLLS ...but that just gives me a warning that it's not referencing them:
5>LINK : warning LNK4199: /DELAYLOAD:Util.dll ignored; no imports found from Util.dll
If I delete a .dll and run the application it crashes and wants to send information to microsoft about the missing .dll so it looks like it's still trying to load all the modules at startup and having a fit as a result.
FYI, my app startup looks something like this:
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 = asse开发者_StackOverflow社区mbly->Load(referencedAssemblyName);
if( a == nullptr )
{
missingDlls->Add(referencedAssemblyName->Name);
}
}
catch(System::Exception^ e)
{
MessageBox::Show("Error loading "+referencedAssemblyName->Name);
}
}
...
The linker's /delayload option only works for DLLs that contain functions compiled to native machine code. The linker already told you that you don't have any.
The likely scenario here is that your DLL actually contains IL, not machine code. Which will happen when you compile the source code with /clr in effect and haven't used #pragma managed to turn off IL generation. IL code needs to be converted to machine code by the jitter.
Your DLL is going to get loaded dynamically, same as /delayload, as soon as the jitter needs type info from the assembly's metadata to generate machine code. To avoid the dependency on the DLL, you'd have to carefully craft your code so the jitter never needs to load types from your assembly. Which is a different problem from avoiding executing a delay-loaded function. The exception's InnerException's stack trace should give you a strong hint how that happened.
精彩评论