I have a native program that uses LoadLibrary() to load a DLL from a specified path other than the working directory. This DLL happens to be a C++/CLI assembly that references a C# DLL. Loading the C++/CLI assembly works fine, but when it tries to call code from the referenced assembly, it fails because it can't find it in the working directory.
Is there any way I can modify the loader's behavior to also try the directory the DLL is in?
If the C++/CLI assembly loads the C# dll statically both need to be in the same folder.
You could try to modify the C++/CLI assembly so that it loads the C# dll with Assembly::Load but this is much more work.
Including the main executable? Yes, it works. It also works if the DLLs the C++/CLI DLL depends on are with the executable, but the C++/CLI DLL is in a different directory. If the executable is in one place and all the other DLLs are in another, it doesn't work.
I managed to get it working. My native API has a function that must be called before any other function, to allow the plugin to perform initialization steps. In it, I did this:
usingnamespace System;
public ref class AssemblyResolver{
public:
static System::Reflection::Assembly ^ResolveEventHandler(System::Object ^sender, System::ResolveEventArgs ^args){
auto sb = gcnew System::Text::StringBuilder();
sb->Append(GetAssemblyDirectory());
constchar * const name = "\\required_assembly.dll";
for (auto p = name; *p; p++)
sb->Append((Char)*p);
return System::Reflection::Assembly::LoadFrom(sb->ToString());
}
//Returns the containing directory of the assembly that contains the function.
static String ^GetAssemblyDirectory(){
auto codeBase = System::Reflection::Assembly::GetExecutingAssembly()->CodeBase;
auto uri = gcnew UriBuilder(codeBase);
auto path = Uri::UnescapeDataString(uri->Path);
return System::IO::Path::GetDirectoryName(path);
}
};
API Instance *initialize(){
auto domain = System::AppDomain::CurrentDomain;
domain->AssemblyResolve += gcnew System::ResolveEventHandler(AssemblyResolver::ResolveEventHandler);
//(Application-specific stuff)
}