如何在 Unity3D 中使用 C dll?

新手上路,请多包涵

我知道 这个类似的问题,但它没有回应我的问题。

我已经使用 Visual Studio 2010 编写了两个 .dll 。一个是 C++,并与用 C++ 编写的 SDK 通信。另一个是该 C++ 库的 C# 包装器,因此它可以在 C# 上下文中使用。

我的计划是,这会让我在 Unity3D 中使用我的代码,但显然情况并非如此。似乎 Unity3D 不允许我将 .dll s 作为资产导入,如果它们不是 .NET 程序集。所以我可以添加我的 C# 包装器,但不能添加 C++ dll。

每当我尝试访问 C++ 库时,这都会导致 DllNotFoundException 。我尝试简单地将 C++ 库复制到 Assets/Plugins 文件夹中,但结果相同。

有没有办法正确地做到这一点?这是我的项目设置中非常重要的部分。

原文由 Lee White 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 583
1 个回答

问题是当 p/invoke 运行时代码调用 LoadLibrary(YourNativeDllName) 时找不到 DLL。

您可以通过确保您的 DLL 在第一次 p/invoke 调用时位于 DLL 搜索路径上来解决此问题。例如通过调用 SetDllDirectory

我个人更喜欢的解决方案是让您的托管代码 p/invoke 调用 LoadLibrary 将完整的绝对路径传递给本机 DLL。这样,当后续 p/invoke 诱导调用 LoadLibrary(YourNativeDllName) 时,您的本机 DLL 已经在进程中,因此将被使用。

 internal static class NativeMethods
{
    [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
    internal static extern IntPtr LoadLibrary(
        string lpFileName
    );
}

然后在你的代码中的某个地方:

 private static IntPtr lib;

....

public static void LoadNativeDll(string FileName)
{
    if (lib != IntPtr.Zero)
    {
        return;
    }

    lib = NativeMethods.LoadLibrary(FileName);
    if (lib == IntPtr.Zero)
    {
        throw new Win32Exception();
    }
}

只需确保调用 LoadNativeDll 将完整路径传递到本机库,然后再调用该本机库的任何 p/invokes。

原文由 David Heffernan 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题