Réglage dllimport par programmation en C#
Je suis en utilisant DllImport
dans ma solution.
Mon problème est que j'ai deux versions de la même DLL construit pour la version 32 bits et une autre pour la version 64 bits.
Ils exposent les mêmes fonctions avec les mêmes noms et les mêmes signatures.
Mon problème est que je dois utiliser deux méthodes statiques qui exposent ces et puis au moment de l'exécution d'utilisation IntPtr
taille pour déterminer la bonne à invoquer.
private static class Ccf_32
{
[DllImport(myDllName32)]
public static extern int func1();
}
private static class Ccf_64
{
[DllImport(myDllName64)]
public static extern int func1();
}
Je dois le faire parce que myDllName32
et myDllName64
doit être constante et je n'ai pas trouvé un moyen de le régler au moment de l'exécution.
Quelqu'un aurait-il une solution élégante pour cela j'ai donc pu se débarrasser de la duplication de code et la constante IntPtr
taille de la vérification.
Si je pourrais définir le nom de fichier, je n'aurais plus qu'à vérifier une fois et j'ai pu me débarrasser d'une tonne de code à répétition.
OriginalL'auteur Matt | 2009-08-23
Vous devez vous connecter pour publier un commentaire.
Vous pouvez probablement obtenir ce avec la
#if
mot-clé. Si vous définissez une compilation conditionnelle symbole appeléwin32
, le code suivant va utiliser win32-bloc, si vous l'enlever, il va utiliser l'autre bloc:Cela signifie probablement que vous pouvez supprimer la classe d'emballage que vous avez maintenant:
Pour des raisons de commodité, je suppose que vous pouvez créer des configurations de build pour contrôler le symbole de compilation.
Alors qu'il travaille, cette approche débouche sur la duplication de code de l'affiche originale veut éviter, en plus de vous limite à la compilation séparée des versions 32 et 64 bits. Vous pouvez supprimer la duplication de code et de continuer à cibler à la fois les versions 32 et 64 bits avec une DLL compilée/EXE en prenant deanis de l'approche à utiliser SetDllDirectory, ou de la mienne pour utiliser la fonction LoadLibrary.
OriginalL'auteur Fredrik Mörk
Je préfère le faire en utilisant la LoadLibrary appel de kernel32.dll pour forcer un particulier de la DLL à charger à partir d'un chemin d'accès spécifique.
Si vous nommez votre 32-bit et 64-bit Dll le même, mais les a placés dans des chemins différents, vous pouvez utiliser le code suivant pour charger le bon en fonction de la version de Windows que vous exécutez. Tout ce que vous devez faire est d'appeler ExampleDllLoader.LoadDll() AVANT tout code référençant le ccf classe est référencé:
Cela ne devrait pas exiger de droits d'administrateur, aussi longtemps que l'utilisateur a les droits de lecture de la DLL est chargée. Je l'ai utilisé dans des situations où un utilisateur normal est en cours d'exécution de l'application.
OriginalL'auteur Josh Sklare
Je sais que c'est une très vieille question (je suis nouveau, est-ce mauvais pour répondre à une question aussi ancienne?), mais j'ai juste eu à résoudre ce même problème. J'ai eu dynamiquement référence à un 32-bit ou 64-bit DLL basé sur l'OS, tandis que mes .EXE est compilé pour n'Importe quel PROCESSEUR.
Vous pouvez utiliser DLLImport, et vous n'avez pas besoin d'utiliser la fonction LoadLibrary().
Je l'ai fait en utilisant SetDLLDirectory. Contrairement au nom,
SetDLLDirectory
ajoute à la DLL chemin de recherche, et ne remplace pas le chemin d'accès complet. Cela m'a permis d'avoir une DLL avec le même nom ("TestDLL.dll" pour cette discussion) dans Win32 et Win64 sous-répertoires, et appelé de manière appropriée.OriginalL'auteur deanis
Pourquoi ne pas les intégrer dans une méthode?
Eh bien une fois que vous enveloppent, vous n'avez pas à vous inquiéter à ce sujet.
OriginalL'auteur ChaosPandion
Une autre option est d'avoir à la fois 32 et les versions 64 bits de la DLL non managée ont le même nom, mais de vivre dans des dossiers distincts dans votre sortie de la construction (x86\ x64\).
Ensuite, votre installateur ou à tout autre que vous êtes à la distribution de ce qui est mis à jour de sorte qu'il sait installer la DLL appropriée pour la plate-forme de l'installation.
OriginalL'auteur Zack Elan
vous pouvez créer deux méthodes et en choisir un dans un moment de l'exécution, de sorte que vous pouvez garder
Any CPU
}
OriginalL'auteur GSerjo
Vous ne pouvez pas le faire comme vous le souhaitez. Vous avez besoin de penser à la
DllImport
en tant qu'attribut de métadonnées qui est utilisé au moment de la compilation. En conséquence, vous ne pouvez pas modifier la DLL c'est de l'importation de façon dynamique.Si vous voulez garder votre code managé s'adressant à "any CPU" alors, vous avez besoin d'importer à la fois les versions 32 bits et 64 bits des bibliothèques enveloppé comme deux différentes fonctions que vous pouvez appeler en fonction de l'environnement d'exécution ou de l'utilisation supplémentaire de l'API Win32 appels à la fin de la charge la version correcte de la non géré assemblée au moment de l'exécution et de supplémentaires Win32 appels pour exécuter les méthodes requises. L'inconvénient, c'est que vous n'aurez pas le temps de compilation de soutien pour tous de ce type de code pour le type de sécurité, etc.
OriginalL'auteur Scott Dorman
Hmm, je me demandais si vous pouviez créer une interface, puis une classe avec des méthodes basées sur la 32 bits et 64 bits dll.
Je ne sais pas si il y a une méthode explicite pour déterminer si vous utilisez la version 64 bits, mais la suite pourrait fonctionner: autoriser le code unsafe et ont une mauvaise fonction reçoit un pointeur vers une adresse, puis de déterminer si le pointeur est de 4 ou 8 octets la taille. Sur la base du résultat déterminer la mise en œuvre de l'interface pour créer.
OriginalL'auteur Brent Scriver
Vous pouvez déterminer si vous exécutez 64Bits ou non en cochant la taille de la IntPtr type (qui est appelé native int de toute façon).
Ensuite, vous pouvez charger le juge approprié DLL à l'aide d'un importés LoadLibraryW appeler, obtenir le pointeur de fonction à l'aide de GetProcAddress, et puis, découvrez Maréchal.GetDelegateForFunctionPointer
- Ce pas aussi compliqué que cela pourrait ressembler. Vous devez DllImport les deux LoadLibraryW et GetProcAddress.
OriginalL'auteur Robert Giesecke