Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a C++ dll in Unity3D?

Tags:

c++

c#

dll

unity3d

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.

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 .dlls as Assets if they are not a .NET assembly. So I can add my C# wrapper, but not the 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.

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

like image 792
Lee White Avatar asked Apr 10 '13 10:04

Lee White


1 Answers

The problem is that the DLL is not being found when the p/invoke runtime code calls 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.

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.

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.

like image 189
David Heffernan Avatar answered Sep 29 '22 17:09

David Heffernan