Search Unity

DllNotFoundException when depend on another dll

Discussion in 'Scripting' started by halhx, Sep 27, 2009.

  1. halhx

    halhx

    Joined:
    Aug 25, 2009
    Posts:
    2
    Hi All,

    I'm working with Plugins and was able to get the basic example dll working as described in the documentation section (http://unity3d.com/support/documentation/Manual/Plugins.html)

    However, when i use my real dll for my project, I kept having a problem with DllNotFoundException. (Even though I did everything exactly like the basic example)

    So after some investigation, I figured out the message is misleading and in fact, this is because my dll depends on another dll. Does anyone know what I should do to load my dll in this case.

    To demonstrate my situation, i created 2 dlls, 1 depends on the other.

    MathFuncsDll.dll is the main one which has Subtract2 and Multiply2 calling into Subtract and Multipy of Math2.dll

    Any help are very much appreciated.

    Best
    - halhx

    Here is my unity script:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Runtime.InteropServices;
    4.  
    5. public class EmoEngineTest : MonoBehaviour {
    6.  
    7.     [DllImport("MathFuncsDll")]
    8.     private static extern double Subtract2(double a, double b);
    9.    
    10.     // Use this for initialization
    11.     void Start () {
    12.         print(Subtract2(8,2));
    13.     }
    14.    
    15.     // Update is called once per frame
    16.     void Update () {
    17.     }
    18. }
    19.  
    20.  

    Here is my MathFuncsDll header:
    Code (csharp):
    1.  
    2. extern "C"
    3. {
    4.     __declspec(dllexport) double Subtract2(double a, double b);
    5.  
    6.     // Returns a * b
    7.     __declspec(dllexport) double Multiply2(double a, double b);
    8.  
    9. }
    10.  
    Here is my MathFuncsDll cpp file:

    Code (csharp):
    1.  
    2. #include "MathFuncsDll.h"
    3. #include "Math2.h"
    4. #include <stdexcept>
    5. using namespace std;
    6. double Subtract2(double a, double b)
    7. {
    8.     return Subtract(a, b);
    9. }
    10.  
    11. double Multiply2(double a, double b)
    12. {
    13.     return Multiply(a, b);
    14. }
    15.  
    Here is my Math2 header

    Code (csharp):
    1.  
    2. extern "C"
    3. {
    4.     // Returns a - b
    5.     __declspec(dllexport) double Subtract(double a, double b);
    6.  
    7.     // Returns a * b
    8.     __declspec(dllexport) double Multiply(double a, double b);
    9. }
    10.  

    Here is my Math2 cpp file
    Code (csharp):
    1.  
    2. #include "Math2.h"
    3. #include <stdexcept>
    4. using namespace std;
    5. double Subtract(double a, double b)
    6. {
    7.     return a - b;
    8. }
    9. double Multiply(double a, double b)
    10. {
    11.     return a * b;
    12. }
    13.  
     

    Attached Files:

  2. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Can you send an e-mail to support@unity3d.com about this issue? I doubt you will need to attach any code - I think it is just about whether Unity can load a chain of DLLs or just one.
     
  3. dannyxyz22

    dannyxyz22

    Joined:
    Jun 16, 2009
    Posts:
    20
    Use the dependency walker (google for it, it's a free download from MicroSoft, I think). It will tell you which dll's you are missing.
     
  4. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Move the dependent DLL to the editor root folder (not the assets folder), I have several closed tickets on this problem. (long story, months of back and forth communciation, end result, no resolution)

    c:\program files\unity\editor

    After you place the DLL in that folder, give it another go.
     
    Derik1995, LaserWzzrd and gever like this.
  5. hightechdan

    hightechdan

    Joined:
    Sep 13, 2009
    Posts:
    8
    Do you know of any workaround for a dependent dll that is a different version of one already in the editor? (i.e. fmodex.dll) I've managed to get my project working when I build and run by calling a function from the dependent before using the main dll, but that didn't solve the problem of running in the editor.
     
  6. Kyle.WTF

    Kyle.WTF

    Joined:
    Dec 15, 2009
    Posts:
    12
    Works great, just upgraded to 2.6.1f3 from using 2.5. DLLs had worked fine just sitting in assets folder but broke after upgrading. Popping the DLL that two others used into that location seems to have fixed the problem.
     
  7. parks

    parks

    Joined:
    Apr 22, 2010
    Posts:
    1
    Hi

    I'm also having the exact same problem. I tried copying the dlls in unity editor, in assets and in plugins but no luck there. The version of my unity is also 2.6.1f3.

    Help is much appreciated. Thanks!
     
  8. reissgrant

    reissgrant

    Joined:
    Aug 20, 2009
    Posts:
    726
    Parks, place your dependent dll in the Unity exe root folder while the main dll that calls the dependent function goes into your plugins folder.

    Are you sure you're exporting your functions properly?

    I would suggest downloading the dll's in this thread and see if you can get them to work; they do work if placed in the proper locations. If they do work for you, then you know it's a fault with your exported functions or includes. If not then it might be something else...
     
  9. Sbd

    Sbd

    Joined:
    Jun 16, 2008
    Posts:
    36
    Same problem here. Using the ODBC dll from SQLAnywhere it says it can't find "dbdata.dll", which should be inside the ODBC dll according to their website... Adding the ODBC dll to the Editor folder does not resolve the issue.

    Any ideas?
     
  10. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    a dll can not be inside another dll

    Sure you understood their explanations?
     
  11. reissgrant

    reissgrant

    Joined:
    Aug 20, 2009
    Posts:
    726
    Sbd, it sounds like you need to include "dbdata.dll" as well, in your Unity.exe directory.
     
  12. Sbd

    Sbd

    Joined:
    Jun 16, 2008
    Posts:
    36
    Yeah, it's not inside the dll, they have baked the functionality into the "iAnywhere.Data.SQLAnywhere.dll", which I have included.

    Problem is that dbdata.dll does not seem to exist anywhere on my computer. Strange since I have the same code working in a C# forms application.

    Might be that the windows 7 search is not searching as good as I want it too :?
     
  13. almo

    almo

    Joined:
    Jul 14, 2010
    Posts:
    83
    I'm having this trouble with a built Win32 executable. Works fine when running in the editor. I've tried including XInputInterface in the folders of the built exe, but to no avail.

    DllNotFoundException: XInputInterface
    XInputDotNetPure.GamePad.GetState (PlayerIndex playerIndex, GamePadDeadZone deadZone)
    XInputDotNetPure.GamePad.GetState (PlayerIndex playerIndex)
    PadScript.Update ()
     
  14. ikriz

    ikriz

    Joined:
    Dec 3, 2009
    Posts:
    98
    Lets say you also get this error and you have a plugins directory in your assets folder in that plugins directory you have a folder with your plugin name and it contains a dll file. Like This:

    Assets/Plugins/MySuperPlugin/SuperPlugin.dll

    What helped for me was to modify my DllImport lines by adding the Directory name to it so instead of

    [DllImport "SuperPlugin"]

    it becomes

    [DllImport "MySuperPlugin/SuperPlugin"]

    This keeps my assets folder and root directory clean and uncluttered :) oh... and it works :)
     
    cecyliaw likes this.
  15. imtrobin

    imtrobin

    Joined:
    Nov 30, 2009
    Posts:
    1,548
    Hmm, I'm facing a similar issue. I manged to get it working by putting the dlls in the exported .exe.

    It doesn't work when I put all of them in Plugins folder. I can see the dlls in data\Plugins folder fine however the log file says the DllNotFoundException when it is clearly there. Is this supposed to work?
     
  16. mpavlinsky

    mpavlinsky

    Joined:
    Oct 20, 2011
    Posts:
    8
    I am experiencing this same issue. My situation may be a bit more unique because I am deploying to an android device so I have a bunch of .so files. I've tried moving the files into the Editor directory as suggested in this thread (I tried this with only the dependant plugins there, only the plugins that are depended on, all the plugins, and none) and it has no effect.

    Has anyone had any success with dependent shared objects on android?
     
  17. valyard

    valyard

    Unity Technologies

    Joined:
    Jun 4, 2010
    Posts:
    291
    Anyone fixed this?
    .NET dll in Plugins folder uses c++ dll which is there too but Unity can't find this c++ dll whatever I do.
    The only thing that worked is to put this c++ dll in Unity3d/Editor folder. Which seems to be a dirty hack.
     
  18. Nodin_T

    Nodin_T

    Joined:
    Aug 14, 2012
    Posts:
    2
    It works, thanks a lot
     
  19. Nodin_T

    Nodin_T

    Joined:
    Aug 14, 2012
    Posts:
    2
    It works, thanks a lot
     
  20. bdawson

    bdawson

    Joined:
    Sep 13, 2012
    Posts:
    4
    One slightly less hacky workaround. In the editor script that uses your .NET DLL, make copy the C++ dll into the unity exe folder. Do to project specific work, we had to do this.
     
  21. peteyg

    peteyg

    Joined:
    Sep 14, 2012
    Posts:
    2
    Hello there,

    I have written a DLL which is dependant on a DLL. This second DLL in turn is dependent on 2 more DLLs.

    When I copy all DLL's into the editor folder (as mentioned in the messages above), I am getting the DLLNotFoundException. However, when I build the project into a standalone Win app and copy all of the DLL's into the folder where the app was built, I am able to access my DLL's.

    Are there any ideas as to why a standalone project exe would work properly but the in-editor game mode does not resolve properly? Any help would be much appreciated in this matter; it is difficult to develop using the DLL I have created if I cannot access it within the editor.

    Thanks!
     
  22. benni05

    benni05

    Joined:
    Mar 17, 2011
    Posts:
    60
    I second what mpavlinsky said about a similar effect when deploying a .so library that depends on another .so on Android. This also leads to a DllNotFoundException when running the app on the Android device.

    Any idea how to circumvent this problem?

    Ben
     
  23. bibbinator

    bibbinator

    Joined:
    Nov 20, 2009
    Posts:
    507
    Hi,
    I wrote the Cruncher plugin and I also depend upon another DLL and had a similar problem for an editor plugin. I came up with a relatively decent solution I think. Basically I use the static constructor method to check if the path I want to keep all my DLLs exists, and if it doesn't I add it. Then I dump all my DLLs in there so they can be accessed from any other code within my process. Note that this won't permanently modify the path, only the execution environment path, so it doesn't have any side effects that I know.


    Code (csharp):
    1.  
    2. public class MyPluginClass
    3. {
    4.     static MyPluginClass()
    5.     {
    6.         String currentPath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process);
    7.         String dllPath = Environment.CurrentDirectory + Path.DirectorySeparatorChar + "Assets" + Path.DirectorySeparatorChar + "Plugins";
    8.         if(currentPath.Contains(dllPath) == false)
    9.         {
    10.             Environment.SetEnvironmentVariable("PATH", currentPath + Path.PathSeparator + dllPath, EnvironmentVariableTarget.Process);
    11.         }
    12.     }
    13. }
    Basically the OS will search the current working directory and then look at the other known paths. This adds a known path of your choosing. I think this should work on runtime apps too (although you wouldn't want to keep your DLLs in the Assets folder because it doesn't exist, I recommend a folder called StreamingAssets which Unity will copy for you on build).

    Notes:
    * This allows a better user experience for native plugins on the Asset Store because the user doesn't have to copy the DLL to another directory outside Assets, and you don't have to try and copy it in code which could fail depending upon user permissions.
    * For those that don't know C# well, a static constructor is the same as a normal constructor for a class, except it's static which means it's called only once for the whole process lifetime, so it's a good place to add our path. Constructors, static or normal, are always simply the same name of the class and are defined inside the class. E.g. the same level as an Awake or Start method, just name it the same as the class name with no return value.

    Hope this helps,
    Brett
     
    Last edited: Sep 22, 2012
    AnonUser84727 likes this.
  24. WhiteGollum

    WhiteGollum

    Joined:
    Apr 19, 2013
    Posts:
    2
    Bibbinator,

    I have a problem trying to use one external DLL, that I think it could be solved with you method, but I cannot get the clue to achieve it.

    I am trying to use an external DLL (OpenCvSharpExtern.dll) that depends on another DLLs (cxcore210.dll).If I use my code on the unity IDE or as an executable, I need to put the DLLs in the same root folder as the exe file.

    When I try to execute on Android, I got the same error (DLLNotFoundException: cxcore210), but I do not know how to solve this on Android, or where to put the dlls.

    Have you faced a similar problem? Could it be solved with your method specifiying a DLL folder inside Android?
     
  25. bibbinator

    bibbinator

    Joined:
    Nov 20, 2009
    Posts:
    507
    I think the solution I use should work for this too because you're just adding a path to your DLL in the current process. I have used this a few times and it has always worked for me.

    Good luck!
     
  26. codingrower

    codingrower

    Joined:
    Aug 17, 2013
    Posts:
    1
    Works for me too!
     
  27. valyard

    valyard

    Unity Technologies

    Joined:
    Jun 4, 2010
    Posts:
    291
    You know it's not a proper solution, right?
     
  28. bibbinator

    bibbinator

    Joined:
    Nov 20, 2009
    Posts:
    507
    Yeah, placing a DLL in the editor folder isn't a good way to do this. Use my solution above as it only takes a few lines of code and works everywhere.
     
  29. k0mbain

    k0mbain

    Joined:
    Nov 1, 2012
    Posts:
    22
  30. maddymac

    maddymac

    Joined:
    Sep 3, 2012
    Posts:
    5
  31. V-Portela

    V-Portela

    Joined:
    Nov 7, 2013
    Posts:
    6
    Worked for me, thank you very much

     
  32. silentslack

    silentslack

    Joined:
    Apr 5, 2013
    Posts:
    393
    Worked for me too :D Thank goodness for this thread
     
  33. Junhak_Kim

    Junhak_Kim

    Joined:
    May 13, 2014
    Posts:
    4
    Worked for me too. Thank.
     
  34. AndyMartin458

    AndyMartin458

    Joined:
    Jul 15, 2012
    Posts:
    59
    I really do want to do it the fancy way instead of putting it in the editor folder, but my DLL keeps timing out. If you have any other tips that would be great.
     
  35. tulakan

    tulakan

    Joined:
    Oct 8, 2014
    Posts:
    1
    I think I'm gonna go this way, but sorry for stupid question. Where to place this snippet into? every file that call dll? or just make new file and call it?

    Thank you
     
  36. bibbinator

    bibbinator

    Joined:
    Nov 20, 2009
    Posts:
    507
    It's a static constructor and so it gets called once the first time something initializes the class. So put it in the class that has methods that require the plugin to be there.
     
    tulakan likes this.
  37. merlock18

    merlock18

    Joined:
    Dec 30, 2013
    Posts:
    28
    Right, so this snippet class here sets the environment variable "PATH" to our plugin path. Very nice but it doesn't seem to be working for me for Unity 5. (.0.f1 I think)
    Is this right?

    public class Uses3DOF : MonoBehaviour {
    //YOUR CODE COPY PASTED
    public class MyPluginClass
    {
    static MyPluginClass()
    {
    string currentPath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process);
    string dllPath = Environment.CurrentDirectory + Path.DirectorySeparatorChar + "Assets" + Path.DirectorySeparatorChar + "Plugins";
    if(currentPath.Contains(dllPath) == false)
    {
    Environment.SetEnvironmentVariable("PATH", currentPath + Path.PathSeparator + dllPath, EnvironmentVariableTarget.Process);
    }
    }
    }
    //END YOUR CODE

    uint id = 0;
    void Start () {
    MyPluginClass plug = new MyPluginClass (); //So instantiate a call to your class which calls the constructor automagically
    id = SS.uStart (); //static dll function calls.
    }
     
    coldpl_ay likes this.
  38. bibbinator

    bibbinator

    Joined:
    Nov 20, 2009
    Posts:
    507
    @merlock18

    I'm not sure if you're using the new Cruncher 2 for Unity 5 or the older version. In Unity 5, please click each plugin/dll and check that it's properly configured settings for each platform. Let me know if that doesn't work.
     
  39. merlock18

    merlock18

    Joined:
    Dec 30, 2013
    Posts:
    28
    Im not using Cruncher. I was just trying to follow your solution for dll nesting. And yes, the dlls are all set to the x86_x64 platform.

    I ma looking at the DebugLog I have printing the Environment variables before and after calling the SetEnvironmentVariables and its definitely changing the variable properly.
     
  40. merlock18

    merlock18

    Joined:
    Dec 30, 2013
    Posts:
    28
    Ignore... I had forgot I created the dll using the Platinum API maker. Totally not compatible with Unity.
     
  41. bibbinator

    bibbinator

    Joined:
    Nov 20, 2009
    Posts:
    507
    Glad you got it sorted out! Sorry about the brain freeze and thinking this was a Cruncher question :)
     
  42. ComicSeansMyomo

    ComicSeansMyomo

    Joined:
    Jul 2, 2014
    Posts:
    1
    I am still having this problem with dependent dll's in Unity5. I have a native dll for a plugin I made, plugin.dll, but it depends on another native cpp dll dependency.dll. In Unity4, I fixed this problem by placing plugin.dll in the appropriate plugins folder, and dependency.dll in the root folder of the project where the Assets folder is; however this solution does not work for me with the same plugin and dependency in a Unity5 project.

    Has Unity5 changed where it looks for dependencies?

    I'm running Unity5.1.1 on Windows.
     
  43. pellen

    pellen

    Joined:
    Sep 8, 2015
    Posts:
    1
    我也是 啊
     
  44. bilke

    bilke

    Joined:
    Jul 13, 2012
    Posts:
    54
  45. coldpl_ay

    coldpl_ay

    Joined:
    Jan 20, 2014
    Posts:
    36
    Hi,
    Thank you for your kind reply. It helped me a lot, but it still seems a problem to me.I can load C++ dll when in editor when using "PATH", but when unity export the program to PC exe, it cannot load dll and still shows the DllnotFoundException when the dll still in Plugins folder.
     
  46. wl570311408

    wl570311408

    Joined:
    Jan 8, 2018
    Posts:
    1
    whether your dll built in windows, used in mac or in reverse? after build and use in same platform, ok for me. How Stupid I am!
     
  47. georgeq

    georgeq

    Joined:
    Mar 5, 2014
    Posts:
    662
    I have a DLL on my project, it works fine inside the editor, it also works fine when I build the player on my PC, but if I copied the player to another PC I got a DllNotFoundException. There was an entry on the log file telling the DLL was not found, but the path and file name mentioned on the log both existed. The problem was a dependent DLL the way I solved it was by changing the runtime library to static instead of DLL. I think this is the best solution.

    dll.png
     
    Last edited: Jul 14, 2018
  48. NickLandry

    NickLandry

    Joined:
    Oct 12, 2016
    Posts:
    26
    I have a similar problem trying to use one of our (Microsoft) cloud SDKs in Unity. I have a managed DLL that is itself dependent on 2 native DLLs. I cannot/don't want to edit either since they are official SDKs. Also, changing the path would only work on Windows, and I need this to work on iOS, Android and UWP too. Is there an elegant solution to this using Unity 2018.2.0f2?
     
    jamesroche likes this.
  49. AnonUser84727

    AnonUser84727

    Joined:
    Nov 16, 2018
    Posts:
    3
    Hell yeah thanks
     
  50. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    974
    AppDomain.AssemblyResolve is a part of .net standard 2.0, so I think it will work in Unity 2018, though I haven't tested it.

    In other, non-unity, projects, I've used code something like this:

    Code (csharp):
    1. public class ClassThatReferencesExternalDll
    2. {
    3.   public static ClassThatReferencesExternalDll
    4.   {
    5.     AppDomain.CurrentDomain.AssemblyResolve += ResolveDependency;
    6.   }
    7.  
    8.   ResolveDependency(object sender, ResolveEventArgs args)
    9.   {
    10.     if (args.Name == "Dependency, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null") // use your dependency's strong name here
    11.     {
    12.       var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); // This assembly's path
    13.       var path = Path.Combine(dir, "Dependency.dll"); // Assume the dependency is adjacent to this assembly
    14.       return Assembly.LoadFile(path);
    15.     }
    16.     else
    17.       return null;
    18.   }
    19. }