c ++ dll的unity3d插件中的DllNotFoundException

Raj*_*Raj 8 unity-game-engine

我正在研究Unity插件项目并尝试从c#文件导入c ++本机dll.但我不断得到dllnotfoundexception.

c ++ dll代码:

extern "C" {
extern __declspec( dllexport ) bool IGP_IsActivated();
}
Run Code Online (Sandbox Code Playgroud)

c#代码:

[DllImport("mydll")]
    private static extern bool IGP_IsActivated();
Run Code Online (Sandbox Code Playgroud)

Dll到位,FIle.Exists正常工作.所有依赖的dll都存在于同一层次结构中,但我仍然在dllnotfound异常中结束.

任何帮助,非常感谢!!

Lar*_*lke 9

感谢这个Unity论坛帖子,我提出了一个很好的解决方案,可以PATH在运行时修改-environment变量:

  • 放入所有 DLL(Unity接口的DLL及其依赖的DLL)Project\Assets\Wherever\Works\Best\Plugins.
  • 将以下静态构造函数放入使用该插件的类中:

    static MyClassWhichUsesPlugin() // static Constructor
    {
        var currentPath = Environment.GetEnvironmentVariable("PATH",
            EnvironmentVariableTarget.Process);
    #if UNITY_EDITOR_32
        var dllPath = Application.dataPath
            + Path.DirectorySeparatorChar + "SomePath"
            + Path.DirectorySeparatorChar + "Plugins"
            + Path.DirectorySeparatorChar + "x86";
    #elif UNITY_EDITOR_64
        var dllPath = Application.dataPath
            + Path.DirectorySeparatorChar + "SomePath"
            + Path.DirectorySeparatorChar + "Plugins"
            + Path.DirectorySeparatorChar + "x86_64";
    #else // Player
        var dllPath = Application.dataPath
            + Path.DirectorySeparatorChar + "Plugins";
    
    #endif
        if (currentPath != null && currentPath.Contains(dllPath) == false)
            Environment.SetEnvironmentVariable("PATH", currentPath + Path.PathSeparator
                + dllPath, EnvironmentVariableTarget.Process);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 添加[InitializeOnLoad]到类以确保构造函数在编辑器启动时运行:

     [InitializeOnLoad]
     public class MyClassWhichUsesPlugin
     {
         ...
         static MyClassWhichUsesPlugin() // static Constructor
         {
             ...
         }
      }
    
    Run Code Online (Sandbox Code Playgroud)

使用此脚本,无需复制DLL.Unity编辑器在Assets/.../Plugins/...-folder中找到它们,可执行文件在..._Data/Plugins-directory中找到它们(在构建时它们会自动复制).

  • 我无法在Unity 2017.3.1f1中使用静态功能。在运行时,我得到:“ UnityException:不允许从MonoBehaviour构造函数(或实例字段初始化程序)中调用get_dataPath,而应在Awake或Start中调用它。” 我将其切换为使用Awake(),并且在我的构建中以及编辑器和中都能正常工作。 (2认同)

Raj*_*Raj 5

好吧,我让它工作了。对于可能遇到此问题的其他人,如果您有多个 dll,则需要将辅助 dll 放在 Unity 编辑器的根级别(例如 C:\Program Files\Unity\Editor),并将脚本中实际引用的 dll 放入插件文件夹。这对我有用。

  • dll 文件的更好位置是在项目文件夹中。只需将 dll 文件放在与“Assets”和“Library”文件夹相同的文件夹中。 (7认同)
  • 我尝试了所有这些解决方案几个小时……结果我的外部 DLL 是 32 位的,而我的 Unity 项目是 64 位的。得到了`DllNotFoundException`,所以被引导到花园小径上......另一件需要注意的事情。 (3认同)
  • 即使我在构建后将 dll 文件放在项目目录和与 exe 文件相同的文件夹中,我也一直得到这些异常。是否需要 Visual C++ Redistributable?我从 Visual C++ 2008 SP1 构建 dll 并安装了 Microsoft 网站上可用的所有 Visual C++ 2008 Redistributable 仍然得到在其他机器上找不到的异常 dll。 (2认同)

sir*_*nce 5

将 DLL(s) Unity 接口放在 Project\Assets\Wherever\Works\Best\Plugins 中。

将您的脚本未直接访问的任何依赖项 DLL 放在 Project 中。这将允许您的程序在编辑器中运行。

构建时,再次将依赖项 DLL 文件复制到构建目录的根目录(就在生成的可执行文件旁边)。这应该允许您的应用程序在运行时加载它们。

(提示:您可以使用Dependency Walker查看您的 DLL 并查看它们所依赖的内容。)