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
How to use a C++ dll in Unity3D?
提问by Lee White
I am aware of this similar question, but it does not respond to my problem.
我知道这个类似的问题,但它没有回答我的问题。
I have written two .dll
s 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 Unity3D
does not allow me to import .dll
s as Assets if they are not a .NET
assembly. So I can add my C# wrapper, but not the C++ dll.
我的计划是这会让我在 中使用我的代码Unity3D
,但显然情况并非如此。如果它们不是程序集,似乎Unity3D
不允许我将.dll
s 作为资产导入.NET
。所以我可以添加我的 C# 包装器,但不能添加 C++ dll。
This results in a DllNotFoundException
whenever I try to access the C++ library. I have tried simply copying the C++ library into the Assets/Plugins
folder, 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 LoadLibrary
passing 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 LoadNativeDll
passing 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 以与运行时静态链接。