Loading mixed mode C ++ / CLI.dll (and dependencies) dynamically from unmanaged C ++

I have a managed assembly in C ++. I load dynamically in an unmanaged C ++ application using a standard call to LoadLibrary (). C ++ managed assembly has dependencies on several more managed (C #) assemblies. Everything worked fine until I moved all managed assemblies to a subdirectory of an unmanaged application. To illustrate:

  • Managed C ++. Dll (MyCoolDll.dll)

    • Depending on DotNetDll1.dll
    • Depending on DotNetDll2.dll
  • C ++ Unmanaged Application (MyCoolApp.exe)

    • Loads MyCoolDll.dll via LoadLibrary ("MyCoolDll.dll")

This worked fine until I moved MyCoolDll.dll, DotNetDll1.dll and DotNetDll2.dll to / someSubDirectory (the code in MyCoolApp.exe was updated to LoadLibrary ("someSubDirectory / MyCooldll.dll")

I guess when MyCoolDll.dll is loaded, it tries to find DotNetDll1.dll and DotNetDll2.dll in the working directory, and not in the directory in which it lives.

How can I tell MyCoolDll.dll my dependencies in a subdirectory? This is a library working inside an unmanaged application, so I don’t think I can specify this in app.config or anything else?

+5
source share
2 answers

CLR , , __declspec (dllexport). , .

CLR .config . MyCoolApp.exe.config, , . <probing>, .

+6

, , . , , , , , - DLL , DLL ( ).

1 - , :

void PrepareManagedCode()
{
    // Set up our resolver for assembly loading
    AppDomain^ currentDomain = AppDomain::CurrentDomain;
    currentDomain->AssemblyResolve += gcnew ResolveEventHandler(currentDomain_AssemblyResolve);
}  // PrepareManagedCode()

. FinalPath, , :

/// <summary>
/// This handler is called only when the CLR tries to bind to the assembly and fails
/// </summary>
/// <param name="sender">Event originator</param>
/// <param name="args">Event data</param>
/// <returns>The loaded assembly</returns>
Assembly^ currentDomain_AssemblyResolve(Object^ sender, ResolveEventArgs^ args)
{
    sender;

    // If this is an mscorlib, do a bare load
    if (args->Name->Length >= 8 && args->Name->Substring(0, 8) == L"mscorlib")
    {
        return Assembly::Load(args->Name->Substring(0, args->Name->IndexOf(L",")) + L".dll");
    }

    // Load the assembly from the specified path
    String^ finalPath = nullptr;
    try
    {
        finalPath = gcnew String(ourAssemblyPath) + args->Name->Substring(0, args->Name->IndexOf(",")) + ".dll";
        Assembly^ retval = Assembly::LoadFrom(finalPath);
        return retval;
    }
    catch (...)
    {
    }

    return nullptr;
}
+8

All Articles