12

我正在开发 Unity Plugin 项目并尝试从 c# 文件导入 c++ 本机 dll。但我不断收到 dllnotfoundexception。

c++ dll代码:

extern "C" {
extern __declspec( dllexport ) bool IGP_IsActivated();
}

c#代码:

[DllImport("mydll")]
    private static extern bool IGP_IsActivated();

Dll 已就位且 FIle.Exists 正常工作。所有依赖的 dll 都存在于同一层次结构中,但我仍然以 dllnotfound 异常告终。

任何帮助,非常感谢!

4

8 回答 8

11

感谢这个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);
    }
    
  • 添加[InitializeOnLoad]到类以确保构造函数在编辑器启动时运行

     [InitializeOnLoad]
     public class MyClassWhichUsesPlugin
     {
         ...
         static MyClassWhichUsesPlugin() // static Constructor
         {
             ...
         }
      }
    

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

于 2015-10-14T11:35:23.357 回答
5

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

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

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

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

于 2014-01-25T03:18:52.207 回答
5

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

于 2012-04-04T20:24:55.573 回答
2

确保满足以下检查清单:

  • 插件都应该保存在一个名为 Plugins 的文件夹中。
  • 您的 dll 构建的架构(x86 或 x86_64)必须与 Unity Editor 的架构版本相对应。Unity Editor 32 位不会加载 64 位插件,反之亦然。
  • 如果您的目标是 32 位和 64 位架构,您应该将您的 dll 放在 Plugins 文件夹内的特殊命名文件夹中。32 位 dll 的名称是 Plugins/x86,64 位 dll 的名称是 Plugins/x86_64(x64 也可以)。
  • 必须安装 Visual C++ Redistributables。我有2008年的所有东西。
  • 当您构建所有 dll 时,应将其复制到可执行文件所在的根目录中(并再次为正确的 x86/x64 架构构建)

如果您不断收到命名空间错误,则意味着您正在导入的 dll 具有非托管代码,并且必须将其包装到另一个托管 dll Pugin 中才能工作。

这些线程有点过时但仍然相关

DLLNotFoundException - Unity3D 插件

使用自定义 dll 的 Unity 内部编译器错误

于 2016-01-26T21:31:35.597 回答
2

我花了一天时间处理这个错误。我的问题是 Android 没有得到库并且总是得到和 DDLNotFound 错误。我的解决方案是:

1.- 确保插件文件夹中有正确架构的库。

Plugins/Android/x86 和 Plugins/Android/armeabi-v7a 如果你的构建设置是 FAT(x86&arm)

2.- 检查 Unity 是否将它们识别为库。如果您在“项目”选项卡中选择它们,您应该将它们视为一个库,并且与平台和架构相关。

3.- 构建后(不要关闭 Unity 编辑器!),如果您的库在那里,您可以检查 Temp/StagingArea/libs。如果确实存在这些库,那么这些库将在 APK 中。作为仔细检查,您可以打开 APK(更改为 zip 扩展名)并查看 lib 文件夹中的库。

4.- 在 C# 中,您应该删除库名称中的任何 lib 前缀,例如:

如果您的库名称是“libdosomething.so”,则应将其称为

[DllImport ("dosomething")]

我希望这对你有用:)

干杯。

于 2017-09-27T18:00:01.290 回答
0

只需将 dll 放在 Plugins 文件夹下,这对我有用

于 2014-10-08T10:40:49.740 回答
0

就我而言,我有 DllNotFoundException: ovrplatiformloader

 Unity   : DllNotFoundException: ovrplatformloader
 Unity   :   at (wrapper managed-to-native) Oculus.Platform.CAPI.ovr_UnityInitWrapperAsynchronous(string)
 Unity   :   at Oculus.Platform.AndroidPlatform.AsyncInitialize (System.String appId) [0x00013] in <29065e843b82403894fca6c6f2974090>:0 
 Unity   :   at Oculus.Platform.Core.AsyncInitialize (System.String appId) [0x0004f] in <29065e843b82403894fca6c6f2974090>:0 
 Unity   :   at DBHelper.Start () [0x00019] in <29065e843b82403894fca6c6f2974090>:0 

我的解决方案是:

  1. 重新导入不起作用的文件 (libovrplatformloader.so)
  2. 重构平台/插件架构。:平台/插件/Android32/libovrplatformloader.so。:Platform/Plugins/Android/x86/libovrplatformloader.soPlatform/Plugins/Android/armeabi-v7a/libovrplatformloader.so
  3. 修改 libovrplatformloader.so 的导入设置。将任何平台更改为仅 Android 平台并启用“启动时加载”选项。在 armeabit-v7a 中选择 ARMv7 CPU,在 x86 文件夹中选择 x86 CPU。
于 2020-07-18T05:37:25.510 回答
0

我遇到了同样的问题,这里描述的解决方案不起作用。我觉得我的情况有点不同。我认为我正在导入的 .dll 依赖于其他 .dll 文件。所以我导入了与该 .dll 相关的其他文件(我认为这是不必要的,因为我没有直接在 c# 代码上调用它们)并且解决了这个问题。

于 2022-02-03T19:10:26.730 回答