77 votes

Utilisation d'une DLL 32 bits ou 64 bits dans C # DllImport

Voici la situation, je suis en utilisant un C en fonction de la dll dans mon dot.net application. Il y a 2 dll, on est en 32 bits appelé MyDll32.dll et l'autre est une version 64 bits appelé MyDll64.dll.

Il y a une statique de la variable contenant le nom du fichier DLL: string DLL_FILE_NAME.

et il est utilisé de la manière suivante:

[DllImport(DLL_FILE_NAME, CallingConvention=CallingConvention.Cdecl, EntryPoint=Func1")]
private static extern int is_Func1(int var1, int var2);

Simple jusqu'à présent.

Comme vous pouvez l'imaginer, le logiciel est compilé avec "any CPU" est activée.

J'ai aussi le code suivant pour déterminer si le système doit utiliser le 64 bits fichier ou le 32-bit fichier.

#if WIN64
        public const string DLL_FILE_NAME = "MyDll64.dll";
#else
        public const string DLL_FILE_NAME = "MyDll32.dll";        
#endif

Maintenant vous devriez voir le problème.. DLL_FILE_NAME est défini au moment de la compilation et non pas de la durée d'exécution de sorte que le droit dll n'est pas chargée, selon le contexte d'exécution.

Quelle serait la bonne façon de traiter ce problème? Je ne veux pas de deux de l'exécution de fichiers (un pour les 32 bits et l'autre pour le 64 bits)? Comment puis-je définir DLL_FILE_NAME avant il est utilisé dans le DllImport déclaration?

77voto

Julien Lebosquain Points 20894

J'ai trouvé que le moyen le plus simple de le faire est d'importer les deux méthodes avec des noms différents et d'appeler la bonne. La DLL ne sera pas chargée jusqu'à ce que l'appel soit fait, donc ça va:

 [DllImport("MyDll32.dll", EntryPoint = "Func1", CallingConvention = CallingConvention.Cdecl)]
private static extern int Func1_32(int var1, int var2);

[DllImport("MyDll64.dll", EntryPoint = "Func1", CallingConvention = CallingConvention.Cdecl)]
private static extern int Func1_64(int var1, int var2);

public static int Func1(int var1, int var2) {
    return IntPtr.Size == 8 /* 64bit */ ? Func1_64(var1, var2) : Func1_32(var1, var2);
}
 

Bien sûr, si vous avez de nombreuses importations, cela peut devenir assez lourd à gérer manuellement.

8voto

vcsjones Points 51910

Il y a une statique de la variable contenant le nom de fichier DLL

Ce n'est pas une variable statique. C'est une constante, au moment de la compilation. Vous ne pouvez pas modifier une compilation constante de temps lors de l'exécution.

Quelle serait la bonne façon de traiter ce problème?

Honnêtement, je recommande seulement de ciblage x86 et oublier la version 64 bits, tous ensemble, et de laisser l'exécution de votre application sur WOW64, à moins que votre application a un besoin impérieux d'exécuter en tant qu'x64.

Si il ya un besoin pour x64, vous pouvez:

  • Modifier la Dll d'avoir le même nom, comme MyDll.dll, et à l'installation / l'heure du déploiement, de mettre le droit en place. (Si l'OS est de 64 bits, de déployer la version 64 bits de la DLL, sinon la version x86).

  • Deux compilations séparées au total, un pour les architectures x86 et une pour x64.

2voto

Yahia Points 49011

Ce que vous décrivez est connu comme "side-by-side de l'assemblée" (deux versions de la même assemblée, un de 32 et l'autre en 64 bits)... je pense que vous les trouverez utiles:

Ici vous pouvez trouver une soluce pour exactement votre scénario.NET DLL emballage C++/CLI DLL de la référence d'une DLL native).

RECOMMANDATION:

Juste le construire comme x86 et être fait avec elle... ou d'avoir 2 versions (l'une x86 et une x64)... comme les techniques ci-dessus sont plutôt compliqué...

0voto

Danny Varod Points 8685

J'ai utilisé l'une des approches voulues par vcsjones:

"Modifiez les DLL pour qu'elles portent le même nom, comme MyDll.dll, et au moment de l'installation / du déploiement, placez le bon."

Cette approche nécessite la maintenance de deux plates-formes de construction, mais consultez ce lien pour plus de détails: http://stackoverflow.com/a/6446638/38368

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X