如何在Unity3D中使用C ++ DLL?

时间:2013-04-10 10:42:31

标签: c# c++ dll unity3d

我知道this similar question,但它没有回应我的问题。

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

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

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

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

3 个答案:

答案 0 :(得分:6)

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

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

我个人更喜欢的解决方案是让您的托管代码p /调用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();
    }
}

在调用该本机库的任何p / inv之前,只需确保调用LoadNativeDll传递本机库的完整路径。

答案 1 :(得分:1)

当Unity可以找到您的DLL,但找不到其依赖项时,也会发生这种情况。明显的解决方法是将依赖项DLL也放置到/ Plugins中,或静态链接您的依赖项。

最明显的原因是当您的DLL动态依赖于Visual Studio运行时库时,是使用“属性-> C / C ++->代码生成-> / MD”选项构建的。将其更改为/ MT以静态链接运行时。

答案 2 :(得分:0)

请注意,可以通过在Debug而不是Release中构建Unity DLL来引起DllNotFoundException!

一种可能引起头痛的简单疏忽。