2011-08-10 11 views
5

Mam zarządzany zestaw C++, który ładuję dynamicznie w niezarządzanej aplikacji C++ za pośrednictwem standardowego wywołania LoadLibrary(). Zarządzany zestaw w C++ ma zależności od kilku zarządzanych (C#) zespołów. Wszystko działało dobrze, dopóki nie przeniosłem wszystkich zarządzanych zestawów do podkatalogu aplikacji niezmienionej. Dla ilustracjiŁadowanie trybu mieszanego C++/CLI .dll (i zależności) dynamicznie z niezarządzanego C++

  • zarządzane C++ DLL (MyCoolDll.dll)

    • zależności od DotNetDll1.dll
    • zależności od DotNetDll2.dll
  • Niezarządzane C++ app (MyCoolApp .exe)

    • Ładunki MyCoolDll.dll poprzez LoadLibrary ("MyCoolDll.dll")

ten działa dobrze, aż przeniesiono MyCoolDll.dll, DotNetDll1.dll & DotNetDll2.dll do/someSubDirectory (kod w MyCoolApp. exe został zaktualizowany do LoadLibrary ("someSubDirectory/MyCooldll.dll")

Zgaduję, gdy załadowany jest MyCoolDll.dll, próbuje znaleźć DotNetDll1.dll i DotNetDll2.dll w katalogu roboczym, zamiast katalogu to mieszka w.

Jak mogę powiedzieć MyCoolDll.dll jego zależności żyć w subdir Ektoria? Jest to biblioteka działająca wewnątrz niezarządzanej aplikacji, więc nie sądzę, że mogę to określić w app.config czy cokolwiek innego?

+1

Wow, Hans, to zadziałało! Byłem bardzo wątpliwy, ponieważ MyCoolApp.exe jest po prostu zwykłą starą aplikacją Win32 (nie .NET), więc pomyślałem, że dodanie pliku konfiguracyjnego aplikacji nie pomoże. Dzięki! Czy chcesz napisać to jako odpowiedź zamiast komentarza, a ja oznaczę to jako zaakceptowane? – Jordan0Day

Odpowiedz

5

CLR jest ładowany w niezwykły sposób w tym scenariuszu przez thunk że kompilator wstrzykiwany podczas kompilacji natywnej eksport dla __declspec (dllexport). Takie postępowanie jest w porządku, po prostu nie jest szczególnie szybkie.

CLR wyruszy na poszukiwania pliku .config, aby zainicjować podstawowe AppDomain. I będzie szukał MyCoolApp.exe.config, niezależnie od tego, że to wcale nie jest zarządzany plik wykonywalny. Możesz użyć <probing> element, aby dodać podkatalogi do wyszukiwania złożeń.

8

Myślę, że to, czego szukasz, to niestandardowy przelicznik złożenia. Musiałem użyć jednego do zrobienia tego, co myślę, że próbujesz zrobić - chciałem zlokalizować niektóre biblioteki DLL w folderze, który nie znajdował się w drzewie początkowego niezarządzanego pliku DLL (który ostatecznie załadował kod zarządzany).

Krok 1 jest, aby funkcję można zadzwonić do skonfigurowania rozpoznawania nazw:

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

wtedy rozpoznawania. Przykład ten ma globalny ourFinalPath który w danym przypadku byłby dodatkowy Folder uzywasz:

/// <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; 
} 
+0

To jest ścieżka, którą doszedłem do wniosku, że będę musiał zejść na dół - problem polegał na tym, że nadal wymagałem zależności MyCoolDll.dll w głównym katalogu aplikacji, ponieważ .net nie przeszukałoby podfolderu przed nimi nawet ładowanie MyCoolDll.dll (więc resolver zespołu nie zostanie skonfigurowany jako pierwszy). Ku mojemu zdziwieniu powyższa sugestia Hansa działa (mimo że MyCoolApp.exe nie jest zarządzanym plikiem wykonywalnym). – Jordan0Day

+0

Twoja niezarządzana biblioteka DLL zostanie załadowana zanim konieczne będzie rozstrzygnięcie zespołu. Następnie możesz załadować bibliotekę DLL trybu mieszanego samodzielnie i wywołać konfigurację rozwiązywania zespołu. W przypadku złożonych scenariuszy będziesz go potrzebować; jednak jeśli prosty plik konfiguracyjny działa dla twojego przypadku, świetnie! –

+0

Problem, który widziałem, to moja dll z trybem mieszanym, mający zależności od kilku innych zespołów .NET, więc jeśli nie umieściłbym tych zależności w głównym katalogu zamiast podfolderu, nie byłbym w stanie uzyskać kodu wykonywalnego w mój dll trybu mieszanego, w którym mógłbym podłączyć resolver. – Jordan0Day

Powiązane problemy