none
Dependencies for a mixed mode DLL don't load RRS feed

  • Question

  • Dear all,

    there is a problem in loading the dependencies of a mixed-mode DLL, which has been loaded by an application through LoadLibrary().

    The application is native, it uses some sort of plugin system; the plugins are DLLs which are loaded by the application using LoadLibrary().
    My plugin is a mixed-mode DLL, which is dependent on other pure .NET assemblies. The dependency is a compile-time one: the .NET assemblies are added as a reference in C++/CLI project.

    Now the problem comes: the application starts in the folder %ProgramFiles%\App; the plugin and its dependencies are located in %CommonProgramFiles%\Plugin.
    When the application starts, it loads the plugin using LoadLibrary, and calls a native function from it. As soon as the DLL switches to the managed code and tries to access the type from dependent assembly, .NET tries to load the said assembly. However the search path for the dependent assemblies is %ProgramFiles%\App, so loading of the dependent DLL fails, because the dependent DLL is located in the same folder as the plugin.

    This would be not a problem if the application would be a .NET application: it could load the plugin with LoadFrom, which ensures that the dependent assemblies are loaded from the location of the plugin.

    Is there a way to ensure the correct behaviour?

    Thanks in advance!

    Vladislav
    Friday, December 18, 2009 10:54 AM

Answers

All replies

  • If your plugins are in subdirectories of your hosting application, then you could use AppDomainSetup.PrivateBinPath (here's an example).

    Another solution for managed plugins is to use AppDomainSetup.ApplicationBase. But that requires assemblies to be loaded from managed first. If the first entrypoint is and has to be from native code, then you probably cannot use it.

    Also this article might be helpful: http://support.microsoft.com/kb/309694 (I didn't finish it yet, but it looks somewhat related).

    -Karel
    Saturday, December 19, 2009 1:11 AM
    Moderator
  • Karel, thank you for your reply.
    Do I understand correctly the following:
    1. When I call from native to managed code the very first time, some default AppDomain is implicitly created (and I cannot influence its parameters).
    2. In order to inject my directories into the list of directories used by fusion process, I need to create a new AppDomain at runtime.
    3. The calls from native code will come into the default AppDomain, and need to be marshalled into the new one.
    Perhaps it's a general problem for managed plugins, so I suppose other developers should encounter the problem like this one, too.
    Monday, December 21, 2009 9:31 AM
  • Hello

    I suggest reading these articles about assembly loading

    How the Runtime Locates Assemblies
    http://msdn.microsoft.com/en-us/library/yx7xezcf.aspx

    Understanding The CLR Binder
    http://msdn.microsoft.com/en-us/magazine/dd727509.aspx

    Debugging Assembly Loading Failures
    http://blogs.msdn.com/suzcook/archive/2003/05/29/57120.aspx


    When I call from native to managed code the very first time, some default AppDomain is implicitly created (and I cannot influence its parameters).

    It's the default application domain. There is an API called AppDomain.AppendPrivatePath, but it's obsolete.
    http://blogs.msdn.com/clrteam/archive/2009/05/14/why-is-appdomain-appendprivatepath-obsolete.aspx
    It's suggested to use a config file to set the path or AppDomainSetup.PrivateBinPath. See my answer for your question 2.

    In order to inject my directories into the list of directories used by fusion process, I need to create a new AppDomain at runtime.

    There may be some alternatives:

    1. Register AssemblyResolve in the default app domain, and locate the assembly in your CommonProgramFiles directory in AssemblyResolve event handler.
    http://msdn.microsoft.com/en-us/magazine/dd727509.aspx#id0400042

    2. If you have config file, try specifying the CommonProgramFiles directory in probing section.

    The calls from native code will come into the default AppDomain, and need to be marshalled into the new one.

    Sorry, I don't understand this question. What's the new one?



    Regards,
    Jialiang Ge
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Tuesday, December 22, 2009 6:09 AM
    Moderator
  • Hi Jialiang,

    thank you for your answer, the second link is particularly useful.
    I've read some of the articles you referenced; however they usually deal with the case of fully managed application. (Anyway, I see that my case is not a big difference.)
    The calls from native code will come into the default AppDomain, and need to be marshalled into the new one.

    Sorry, I don't understand this question. What's the new one?
    The new one is the new AppDomain, which (as I assumed) needs to be created in order to inject my directories into the fusion process, and resolve the assembly reference in a correct way.

    Regards,
    Vladislav
    Tuesday, December 22, 2009 4:31 PM
  • the new AppDomain, which (as I assumed) needs to be created in order to inject my directories into the fusion process, and resolve the assembly reference in a correct way.



    I see. Thanks for the clarification. As you said, the data needs to be marshalled into the new appdomain.

    Please feel free to let me know if you have any other questions.
    Regards,
    Jialiang Ge
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Wednesday, December 23, 2009 10:29 AM
    Moderator