C# 如何在 Unity3D 中使用 C++ dll?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15923595/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 18:28:42  来源:igfitidea点击:

How to use a C++ dll in Unity3D?

c#c++dllunity3d

提问by Lee White

I am aware of this similar question, but it does not respond to my problem.

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

I have written two .dlls using Visual Studio 2010. One is in C++, and communicates with an SDK that was written in C++. The other is a C# wrapper for that C++ library, so that it can be used in C# contexts.

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

My plan was that this would let me use my code in Unity3D, but apparently that is not the case. It seems like Unity3Ddoes not allow me to import .dlls as Assets if they are not a .NETassembly. So I can add my C# wrapper, but not the C++ dll.

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

This results in a DllNotFoundExceptionwhenever I try to access the C++ library. I have tried simply copying the C++ library into the Assets/Pluginsfolder, but that gives the same results.

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

Is there a way to do this properly? This is a very vital part of my project setup.

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

采纳答案by David Heffernan

The problem is that the DLL is not being found when the p/invoke runtime code calls LoadLibrary(YourNativeDllName).

问题是当 p/invoke 运行时代码调用LoadLibrary(YourNativeDllName).

You could resolve this by making sure that your DLL is on the DLL search path at the point where the first p/invoke call to it is made. For example by calling SetDllDirectory.

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

The solution that I personally prefer is for your managed code to p/invoke a call to LoadLibrarypassing the full absolute path to the native DLL. That way when the subsequent p/invoke induced call to LoadLibrary(YourNativeDllName)is make, your native DLL is already in the process and so will be used.

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

And then somewhere in your code:

然后在您的代码中的某处:

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();
    }
}

Just make sure that you call LoadNativeDllpassing the full path to the native library, before you call any of the p/invokes to that native library.

LoadNativeDll在调用任何 p/invoke 到该本地库之前,请确保调用将完整路径传递到本地库。

回答by bugmagnet

Note that the DllNotFoundException can be caused by building your Unity DLL in Debug instead of Release!

请注意,在 Debug 而不是 Release 中构建 Unity DLL 可能会导致 DllNotFoundException!

A simple oversight that can cause a headache.

一个可能导致头痛的简单疏忽。

回答by Alexey Podlasov

This also happens when Unity can find your DLL, but is not able to find it's dependencies. Obvious fix is to place dependency DLLs into /Plugins as well, or link your dependencies statically.

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

Less obvious reason is when your DLL depends on Visual Studio runtime library dynamically, i.e.is built with Properties -> C/C++ -> Code Generation -> /MD option. Change it to /MT to link with runtime statically.

不太明显的原因是当您的 DLL 动态依赖于 Visual Studio 运行时库时,使用 Properties -> C/C++ -> Code Generation -> /MD 选项构建。将其更改为 /MT 以与运行时静态链接。