2013-04-10 7 views
6

Ich bin bewusst, this similar question, aber es reagiert nicht auf mein Problem.Wie verwendet man eine C++ DLL in Unity3D?

Ich habe zwei .dll s mit Visual Studio 2010 geschrieben. Eins ist in C++ und kommuniziert mit einem SDK, das in C++ geschrieben wurde. Der andere ist ein C# -Wrapper für diese C++ - Bibliothek, so dass er in C# -Kontexten verwendet werden kann.

Mein Plan war, dass dies ließ mich meinen Code in Unity3D verwenden, aber anscheinend ist das nicht der Fall. Es scheint wie erlaubt mir nicht .dll s als Assets zu importieren, wenn sie keine .NET Assembly sind. So kann ich meinen C# -Wrapper hinzufügen, aber nicht die C++ - DLL.

Dies führt zu einem DllNotFoundException, wenn ich versuche, auf die C++ - Bibliothek zuzugreifen. Ich habe versucht, einfach kopieren Sie die C++ - Bibliothek in den Ordner Assets/Plugins, aber das gibt die gleichen Ergebnisse.

Gibt es eine Möglichkeit, dies richtig zu tun? Dies ist ein sehr wichtiger Teil meiner Projekteinrichtung.

+0

Wie rufen Sie die C++ - DLL? Sie sollten es nicht als Referenz zu Ihrer Lösung hinzufügen. Es ist eine native Ressource. –

+0

@SimonWithehead Ich benutze 'PInvoke' um die C++ Funktionen aufzurufen, mit' [DllImport ("Foo.dll")] '. Es funktioniert, wenn sich die beiden DLLs im selben Ordner befinden, aber ich habe keine Ahnung, wie Unity dlls-Plugins behandelt. –

+0

Welche Lizenz verwenden Sie? Was ist dein Ziel? – aukaost

Antwort

5

Das Problem ist, dass die DLL nicht gefunden wird, wenn der p/invoke-Laufzeitcode LoadLibrary(YourNativeDllName) aufruft.

Sie können dies beheben, indem Sie sicherstellen, dass sich Ihre DLL an dem DLL-Suchpfad befindet, an dem der erste p/invoke-Aufruf erfolgt. Zum Beispiel durch den Aufruf SetDllDirectory.

Die Lösung, die ich persönlich bevorzuge, ist für Ihren verwalteten Code p/rufen Sie einen Aufruf an LoadLibrary übergeben den vollständigen absoluten Pfad an die native DLL. Auf diese Weise, wenn der nachfolgende p/invoke-induzierte Aufruf an LoadLibrary(YourNativeDllName) vorgenommen wird, ist Ihre native DLL bereits im Prozess und wird daher verwendet.

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

Und dann irgendwo im 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(); 
    } 
} 

einfach sicher, dass Sie LoadNativeDll den vollständigen Pfad zur nativen Bibliothek vorbei rufen, bevor Sie eine der p nennen/ruft auf diese native Bibliothek .

+0

Muss ich wirklich den absoluten Pfad zur Bibliothek dafür verwenden? Ich bin nicht die einzige Person, die an diesem Projekt arbeitet, das würde die Sache sehr kompliziert machen ... –

+0

Nun ja. Aber das heißt nicht, dass Sie den Pfad fest codieren müssen. Sie können es zur Laufzeit aufbauen. Legen Sie die native DLL in den gleichen Ordner und die verwaltete DLL und bauen Sie den Pfad auf diese Weise auf. Ihre P/Invoke-Deklarationen verwenden immernoch nur den DLL-Namen, d. H. '" Mydll.dll "'. Aber es kommt nicht weg von der Tatsache, dass das System irgendwie Ihre DLL finden muss. Sie können nicht einfach eine DLL überall hin mitnehmen und hoffen, dass das System sie für Sie findet. –

+0

Ich weiß, dass ich es nicht einfach irgendwo hinstellen kann; Ich hatte gehofft, dass Unity3D es mir erlauben würde, es irgendwie als Abhängigkeit zu spezifizieren, so dass es ähnlich wie beim Zugriff auf C# zugegriffen werden würde.Wenn du sagst, dass ich den Pfad zur Laufzeit aufbauen kann, wie schlägst du vor, dass ich das tue? Unity3D bewegt meine DLL, sobald sie als Plugin importiert wurde, also bin ich mir nicht sicher, wie ich das machen kann. –

0

Beachten Sie, dass die DllNotFoundException verursacht werden kann, indem Sie Ihre Unity DLL in Debug statt in Release erstellen!

Ein einfacher Überblick, der Kopfschmerzen verursachen kann.