none
Load DLL from different path (c++/cli DLL loads managed C# DLL) (help) RRS feed

  • Question

  • I am coming from this topic.

    I created C# DLL and use it inside C++/CLI as another DLL used in another c++ "DLL" call it Main DLL. All dlls have to be under one folder, which is not under exe. Application search and call each dll, but only Main DLL is loaded and used because others are for the Main DLL only not for application.

    Problem with that is DLL path is from application exe view. I resolve it for Main DLL to make SetDLLDirectory and Main DLL can load C++/CLI DLL without problem. Problem is loading DLL from C++/CLI, because loading DLL is different and SetDllDirecoty not working.

    Question is, how to set dll direcotry for C++/CLI DLL to load C# DLL? If it help, I only add reference to C# DLL for C++/CLI DLL and I am able use all C# objects.


    I tried App.Config file or AppDomain and change BaseDirectory. Nothing works. BaseDirectory is changed but it still can't load DLL.


    • Edited by Striebrovlas Wednesday, January 15, 2020 8:00 PM
    Wednesday, January 15, 2020 7:58 PM

Answers

  • Hi Striebrovlas,

    Thank you for posting here.

    We usually use Assembly.Load and Assembly.LoadFrom method to load assembly in .NET Framework.

    Check the following reference:

    Assembly::LoadFrom called from Managed C++ dll

    Hope it could be helpful.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Striebrovlas Thursday, January 23, 2020 9:54 PM
    Thursday, January 16, 2020 6:46 AM
    Moderator
  • Ok, this is helped me

    one solution is from Xingyu Zhao nad Assembly.LoadFrom adding it to AppDomain.AssemblyResolve Event.

    or register DLL in to GAC.

    and runing WPF in new AppDomain I resolved in this topic.


    • Marked as answer by Striebrovlas Thursday, January 23, 2020 9:54 PM
    • Edited by Striebrovlas Thursday, January 23, 2020 9:58 PM
    Thursday, January 23, 2020 9:54 PM

All replies

  • Hi Striebrovlas,

    Thank you for posting here.

    We usually use Assembly.Load and Assembly.LoadFrom method to load assembly in .NET Framework.

    Check the following reference:

    Assembly::LoadFrom called from Managed C++ dll

    Hope it could be helpful.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Striebrovlas Thursday, January 23, 2020 9:54 PM
    Thursday, January 16, 2020 6:46 AM
    Moderator
  • Thanks,

    I discover this post http://olivierhelin.com/blog/c-utils/load-dlls-from-specific-location-instead-of-near-the-exe which help me. I realized that one mistake what I did was wrong path. In c++/cli it is different from C++ and therefore I have to convert string to FileInfo and then convert it back to string. Now my dll is loaded.

    My code converted to c++/cli from link I post:

    System::Reflection::Assembly ^ WPF::WApp::MyResolveEventHandler(System::Object ^ sender, System::ResolveEventArgs ^ args)
    {
    	String ^ assName2 = gcnew String((DllSystem::pathToDll + L"\\my_test_plugin_gui.dll").c_str());
    
    	Assembly ^ result = nullptr;
    	if (args != nullptr && !String::IsNullOrEmpty(args->Name))
    	{
    		//Get current exe fullpath
    		System::IO::FileInfo ^info = gcnew System::IO::FileInfo(Assembly::GetExecutingAssembly()->Location);
    
    
    		//Get folder of the executing .exe
    		auto folderPath = gcnew String(System::IO::Path::Combine(info->Directory->FullName, "Libs"));
    
    		System::IO::FileInfo ^ ninfo = gcnew System::IO::FileInfo(gcnew String(assName2));
    		String ^ folderPathNew = gcnew String(ninfo->Directory->FullName);
    
    		//Build potential fullpath to the loading assembly
    		String ^ assemblyName = args->Name->Split(gcnew array<String ^> { "," }, StringSplitOptions::None)[0];
    		String ^ assemblyExtension = gcnew String("dll");
    		auto assemblyPath = gcnew String(System::IO::Path::Combine(folderPathNew, String::Format("{0}.{1}", assemblyName, assemblyExtension)));
    
    		//Check if the assembly exists in our "Libs" directory
    		if (System::IO::File::Exists(assemblyPath))
    		{
    			//Load the required assembly using our custom path
    			result = Assembly::LoadFrom(assemblyPath);
    		}
    		else
    		{
    			//Keep default loading
    			return args->RequestingAssembly;
    		}
    	}
    
    	return result;
    }

    But new problem arise.

    I created Log and discovered that calling to Resolver is not once but much more time. Sometimes it lead to "lock" becuase when validator execute my vst3, it never stop or when I run it another program which can load vst3 firstly it run without problem but every time in second time, program crash.

    btw. I forgot mention, AppDomain and .Net is new to me, therefore I am not sure if my code is right. Another info I forgot mention, after dll is loaded, it should be able to load it more times. Imagine, application loads my vst3 --> interop.dll --> gui.dll. It is loaded successfully but it must be able to load more times. For example, you have one music instrument (guitar) but you want add another new 3 guitars therefore you must load same vst3 4x and able to use them individualy.


    • Edited by Striebrovlas Thursday, January 16, 2020 2:17 PM make link working on click
    Thursday, January 16, 2020 2:17 PM
  • Maybe it will be better, if possible, load DLL in to AppDomain without Resolver. But every code I found it I didn't understand, because I am not sure if it is loaded in to AppDomain, from all codes on internet it looks like it is loaded in to some object. What I want is:

    Load DLL, it doesn matter if AppDomain or whatever, but I want use my object normaly like this:

    wapp = gcnew WPF::Wapp();
    wapp->Create_App();
    // etc...

    Thursday, January 16, 2020 2:24 PM
  • Ok, this is helped me

    one solution is from Xingyu Zhao nad Assembly.LoadFrom adding it to AppDomain.AssemblyResolve Event.

    or register DLL in to GAC.

    and runing WPF in new AppDomain I resolved in this topic.


    • Marked as answer by Striebrovlas Thursday, January 23, 2020 9:54 PM
    • Edited by Striebrovlas Thursday, January 23, 2020 9:58 PM
    Thursday, January 23, 2020 9:54 PM