Question

J'ai un DLL non géré (le scilexer.dll de l'éditeur de code Scintilla, utilisé par Scintilla.Net de CodePlex ) qui est chargé à partir d'une application gérée creux du composant Scintilla.Net. Les fenêtres application gérée fonctionne sans problème sur 32 et 64 environnements de bits, mais je dois créer des installations différentes qui utilise le 64 ou le 32 scilexer.dll.

Est-il possible de distribuer les deux DLL au format 32 et 64 bits afin que le chargeur de DLL du framework .Net charge la DLL non géré dans le format 32 ou 64 bits selon une option .config ou un « nom chemin magique "choses?

Était-ce utile?

La solution

P / Invoke utilise LoadLibrary pour charger les DLL, et s'il y a déjà une bibliothèque chargée d'un nom donné, LoadLibrary le retourne. Donc, si vous pouvez donner les deux versions de la DLL du même nom, mais les mettre dans des répertoires différents, vous pouvez faire quelque chose comme ça juste une fois avant votre premier appel à une fonction de scilexer.dll, sans avoir besoin de dupliquer vos déclarations 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 + ".");

Autres conseils

Malheureusement, je ne sais rien au sujet de cette DLL particulière. Toutefois, lorsque vous faites le P / Invoke-vous, et vous pouvez faire face à un peu double emploi, il est possible de créer un proxy pour chaque plate-forme.

Par exemple, supposons que vous avez l'interface suivante, qui devrait être mis en œuvre soit par une DLL 32 bits ou 64 bits:

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

Vous créez les procurations:

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

et

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

Et enfin faire une usine qui prend la bonne pour vous:

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

Comme les DLL sont chargées paresseusement la première fois qu'ils sont invoqués, cela fonctionne réellement, en dépit de chaque plate-forme ne pouvant charger la version native est à elle. Voir cet article pour une explication plus détaillée.

Le meilleur que je suis venu avec est le suivant:

  • Répartir ma demande avec deux DLL nommés 64 ou 32
  • Dans le code principal de démarrage sont les suivants:
    
    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");
        }
    }

Vous pouvez mettre le dll system32. Le bit 32 dans syswow64 et le bit 64 dans le réel system32. Pour 32 application bits, lorsque Thay d'accès system32 ils sont redirigés vers Syswow64.

Vous pouvez créer une entrée dans le registre. La clé logicielle a une sous-clé nommée Wow6432Node que l'application 32 bits voir comme la clé du logiciel.

Voici ce que installation de Powershell fait .

non gérés peuvent être dll installés dans le côte à côte GAC avec leurs homologues gérés. Cet article devrait expliquer comment cela fonctionne.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top