Question

J'ai un problème similaire à celui décrit, mais subtilement différent de celui décrit ici (Chargement des assemblys et de leurs dépendances).

J'ai une DLL C++ pour le rendu 3D que nous vendons aux clients.Pour les utilisateurs .NET, nous aurons un wrapper CLR autour.La DLL C++ peut être construite en versions 32 et 64 bits, mais je pense que cela signifie que nous devons avoir deux wrappers CLR puisque le CLR se lie à une DLL spécifique ?

Supposons maintenant que notre client dispose d'une application .NET qui peut être 32 ou 64 bits, et qu'il s'agit d'une application .NET pure, elle laisse au CLR le soin de la résoudre à partir d'un seul ensemble d'assemblys.La question est de savoir comment le code de l'application peut-il choisir dynamiquement entre nos combinaisons CLR/DLL 32 et 64 bits au moment de l'exécution ?

Plus précisément encore, la réponse suggérée à la question susmentionnée est-elle également applicable ici (c.-à-d.créer un gestionnaire ResolveEvent) ?

Était-ce utile?

La solution

J'ai enfin une réponse à cela qui semble fonctionner.

Compilez les versions 32 et 64 bits - gérées et non gérées - dans des dossiers séparés.Demandez ensuite à l’application .NET de choisir au moment de l’exécution le répertoire à partir duquel charger les assemblys.

Le problème avec l'utilisation de ResolveEvent est qu'il n'est appelé que si les assemblys ne sont pas trouvés, il est donc trop facile de se retrouver accidentellement avec des versions 32 bits.Utilisez plutôt un deuxième objet AppDomain dans lequel nous pouvons modifier la propriété ApplicationBase pour qu'elle pointe vers le bon dossier.Vous vous retrouvez donc avec un code du type :

static void Main(String[] argv)
  {
     // Create a new AppDomain, but with the base directory set to either the 32-bit or 64-bit
     // sub-directories.

     AppDomainSetup objADS = new AppDomainSetup();

     System.String assemblyDir = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
     switch (System.IntPtr.Size)
     {
        case (4): assemblyDir += "\\win32\\";
           break;
        case (8): assemblyDir += "\\x64\\";
           break;
     }

     objADS.ApplicationBase = assemblyDir;

     // We set the PrivateBinPath to the application directory, so that we can still
     // load the platform neutral assemblies from the app directory.
     objADS.PrivateBinPath = System.IO.Path.GetDirectoryName(Application.ExecutablePath);

     AppDomain objAD = AppDomain.CreateDomain("", null, objADS);
     if (argv.Length > 0)
        objAD.ExecuteAssembly(argv[0]);
     else
        objAD.ExecuteAssembly("MyApplication.exe");

     AppDomain.Unload(objAD);

  }

Vous vous retrouvez avec 2 ex - votre application normale et une deuxième application de commutation qui choisit les bits à charger.Remarque - Je ne peux pas m'attribuer le mérite des détails de cela moi-même.Un de mes collègues a réfléchi à cela compte tenu de mon pointeur initial.Si et quand il s'inscrira à StackOverflow, je lui attribuerai la réponse

Autres conseils

J'ai pu le faire il y a environ un an, mais je ne me souviens plus de tous les détails.Fondamentalement, vous pouvez utiliser IntPtr.Size pour déterminer quelle DLL charger, puis effectuer le LoadLibrary réel via p/Invoke.À ce stade, vous avez le module en mémoire et vous devriez pouvoir simplement p/Invoquer des fonctions depuis l'intérieur - le même nom de module ne devrait pas être rechargé à nouveau.

Je pense, cependant, que dans mon application, la DLL C++ s'est en fait enregistrée en tant que serveur COM, puis j'ai accédé à ses fonctionnalités via un wrapper .NET généré - donc je ne sais pas si j'ai déjà testé p/Invoking directement.

J'ai rencontré un scénario similaire il y a quelque temps.Une boîte à outils que j'utilisais ne se comportait pas bien dans un environnement 64 bits et je n'étais pas en mesure de trouver un moyen de forcer dynamiquement les assemblys à se lier en 32 bits.

Il est possible de forcer vos assemblys à fonctionner en mode 32 bits, mais cela nécessite de patcher l'en-tête CLR (il existe un outil qui fait cela dans le Framework) et si vos assemblys portent un nom fort, cela ne fonctionne pas.

Je crains que vous deviez créer et publier deux ensembles de binaires pour les plates-formes 32 et 64 bits.

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