Frage

Ich habe eine nicht verwaltete DLL (die scilexer.dll von Editor Scintilla-Code, verwendet von Scintilla.Net von CodePlex ), die von einem verwalteten Anwendung Trog die Scintilla.Net Komponente geladen wird. Die verwalteten Windows-Anwendung läuft problemlos auf beiden 32- und 64-Bit-Umgebungen, aber ich brauche, um verschiedene Installationen zu erstellen, die 64 oder die 32 scilexer.dll verwendet.

Gibt es eine Möglichkeit, beide DLLs in 32 und 64 Bit-Format zu verteilen, so dass die DLL-Loader von .NET Framework die nicht verwaltete DLL in dem 32- oder 64-Bit-Format laden in Abhängigkeit von einiger .config Option oder einer „Pfadnamen Magie "Sachen?

War es hilfreich?

Lösung

P / Invoke verwendet Loadlibrary DLLs zu laden, und wenn es bereits eine Bibliothek mit einem bestimmten Namen geladen ist, wird es Loadlibrary zurück. Also, wenn Sie beiden Versionen der DLL die gleichen Namen geben können, aber sie in verschiedenen Verzeichnissen setzen, können Sie so etwas wie dies nur einmal vor dem ersten Aufruf eine Funktion von scilexer.dll tun, ohne dass Ihre externen Erklärungen kopieren:

    string platform = IntPtr.Size == 4 ? "x86" : "x64";
    string dll = installDir + @"\lib-" + platform + @"\scilexer.dll";
    if (LoadLibrary(dll) == IntPtr.Zero)
        throw new IOException("Unable to load " + dll + ".");

Andere Tipps

Leider, ich weiß nichts über diese besondere DLL. Wenn Sie jedoch die P tun / Invoke selbst, und Sie können mit einer wenig Überschneidungen zu bewältigen, ist es möglich, einen Proxy für jede Plattform zu erstellen.

Zum Beispiel: Angenommen, dass Sie die folgenden Schnittstelle haben, dass entweder durch einen 32- oder 64-Bit-DLL implementiert werden sollten:

public interface ICodec {
    int Decode(IntPtr input, IntPtr output, long inputLength);
}

Sie erstellen die Proxies:

public class CodecX86 : ICodec {
    private const string dllFileName = @"Codec.x86.dll";

    [DllImport(dllFileName)]
    static extern int decode(IntPtr input, IntPtr output, long inputLength);

    public int Decode(IntPtr input, IntPtr output, long inputLength) {
        return decode(input, output, inputLength);
    }
}

und

public class CodecX64 : ICodec {
    private const string dllFileName = @"Codec.x64.dll";

    [DllImport(dllFileName)]
    static extern int decode(IntPtr input, IntPtr output, long inputLength);

    public int Decode(IntPtr input, IntPtr output, long inputLength) {
        return decode(input, output, inputLength);
    }
}

Und schließlich eine Fabrik machen, die das richtige für Sie wählt:

public class CodecFactory {
    ICodec instance = null;

    public ICodec GetCodec() {
        if (instance == null) {
            if (IntPtr.Size == 4) {
                instance = new CodecX86();
            } else if (IntPtr.Size == 8) {
                instance = new CodecX64();
            } else {
                throw new NotSupportedException("Unknown platform");
            }
        }
        return instance;
    }
}

Da die DLLs lazily das erste Mal geladen werden sie aufgerufen werden, das funktioniert tatsächlich, trotz jeder Plattform nur in der Lage ist, um die Version zu laden, die es stammt. Siehe dieser Artikel für eine ausführlichere Erklärung.

Das Beste, was ich habe kommen mit ist die folgende:

  • Verteilen Sie meine Anwendung mit zwei DLLs benannt 64 oder 32
  • Im Hauptstartcode gehören die folgenden:
    
    File.Delete(Application.StartupPath + @"\scilexer.dll");
    {
      // Check for 64 bit and copy the proper scilexer dll
        if (IntPtr.Size == 4)
        {
          File.Copy(Application.StartupPath + @"\scilexer32.dll",
            Application.StartupPath + @"\scilexer.dll");
        }
        else
        {
          File.Copy(Application.StartupPath + @"\scilexer64.dll",
            Application.StartupPath + @"\scilexer.dll");
        }
    }

Sie können die DLL in system32 setzen. Die 32-Bit-in syswow64 und den 64-Bit im realen system32. Für 32-Bit-Anwendung, wenn Thay Zugang system32 sie zu Syswow64 umgeleitet werden.

Sie können einen Eintrag in der Registry erstellen. Der Software-Schlüssel hat einen Unterschlüssel namens Wow6432Node, dass 32-Bit-Anwendung als Software-Schlüssel sehen.

Hier ist, was Powershell-Installationsprogramm führt .

Nicht verwaltete DLLs können in die GAC Seite an Seite mit ihren verwalteten Pendants installiert werden. Dieser Artikel sollte erklären, wie es funktioniert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top