Domanda

ho una DLL non gestita (la scilexer.dll di Scintilla editor di codice, utilizzato da Scintilla.Net da CodePlex ) che viene caricato da un'applicazione gestita trogolo il componente Scintilla.Net. L'applicazione gestita Windows gira senza problemi su entrambi gli ambienti a 32 e 64 bit, ma ho bisogno di creare diverse installazioni che utilizza il 64 o il 32 scilexer.dll.

C'è un modo per distribuire entrambe le DLL in formato 32 e 64 bit in modo che il caricatore DLL del NET Framework carica la DLL non gestita nel formato 32 o 64 bit a seconda qualche opzione config o qualche "nome magico percorso "roba?

È stato utile?

Soluzione

P / Invoke utilizza LoadLibrary per caricare DLL, e se c'è già una biblioteca caricato con un determinato nome, LoadLibrary tornerà esso. Quindi, se si può dare entrambe le versioni della DLL con lo stesso nome, ma metterli in directory differenti, si può fare qualcosa di simile solo una volta prima della prima chiamata a una funzione da scilexer.dll, senza la necessità di duplicare i vostri dichiarazioni extern:

    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 + ".");

Altri suggerimenti

Purtroppo, io non so nulla di questo particolare DLL. Tuttavia, quando si esegue il P / Invoke te stesso, e si può far fronte con un po 'di duplicazione, è possibile creare un proxy per ogni piattaforma.

Per esempio, supponiamo di avere la seguente interfaccia, che dovrebbe essere attuato sia da un DLL a 32 o 64 bit:

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

È possibile creare le deleghe:

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

e

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

E finalmente fare una fabbrica che raccoglie quella giusta per voi:

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

Mentre le DLL vengono caricate pigramente la prima volta che vengono invocati, questo in realtà funziona, nonostante ogni piattaforma solo essere in grado di caricare la versione che è nativo di esso. Vedere questo articolo per una spiegazione più dettagliata.

Il migliore che è venuta in mente è la seguente:

  • Distribuire la mia domanda con due DLL di nome 64 o 32
  • Nel codice di avvio principale sono i seguenti:
    
    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");
        }
    }

È possibile inserire la dll in system32. Il 32 bit in syswow64 e 64 bit nel vero system32. Per l'applicazione a 32 bit, quando thay accesso system32 vengono reindirizzati a Syswow64.

È possibile creare una voce nel Registro di sistema. La chiave software ha una sottochiave denominata Wow6432Node che l'applicazione a 32 bit vedere come la chiave software.

Ecco cosa installatore PowerShell nofollow noreferrer fa .

DLL non gestite possono essere installati in side-by-side con le loro controparti gestiti GAC. questo articolo dovrebbe spiegare come funziona.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top