7
votes

Quelle est la meilleure façon de soutenir plusieurs architectures dans un environnement géré / non géré / non géré?

Fond

Nous avons une bibliothèque .NET qui fait référence à l'une de nos DLL non gérés, disons:

  • dotnet.dll
  • non gérés.dll

    jusqu'à présent, non gérés.dll est seulement 32 bits, donc le dotnet.dll est marqué avec un type de processeur 32 bits.

    Support 64 bits doit être ajouté. Comment organiser les DLL? IL code de dotnet.dll sera le même pour les versions 32 bits et 64 bits.

    Option 1
    • Dossier bibliothèques 32bit
      • dotnet.dll, type CPU de 32 bits
      • non gérés.dll, compilé comme 32 bits
      • Dossier bibliothèques 64 bits
        • dotnet.dll, type CPU de 64 bits
        • nonchanged.dll, compilé 64 bits

          Dans ce cas, un développeur utilisant ces bibliothèques est obligé de faire 2 applications: un un 32 bits et un 64 bits. Mais dans ce cas, le savoir exactement ce qui se passe.

          Option 2

          Ceci est identique à l'option 1 sauf dotnet.dll comporte du type de processeur d'AnyCPU.

          • Dossier bibliothèques 32bit
            • dotnet.dll, type CPU de AnyCPU
            • non gérés.dll, compilé comme 32 bits
            • Dossier bibliothèques 64 bits
              • dotnet.dll, type CPU de AnyCPU
              • nonchanged.dll, compilé 64 bits

                Je n'aime pas celui-ci, car un développeur utilisant ces bibliothèques, lorsque la redistribution de leur application ne peut pas faire de bon travail pour ne pas faire crash sans régler le type de la CPU sur leur application:

                • S'ils utilisent un dossier de bibliothèques de 32 bits, sur un système d'exploitation 64 bits, leur processus se bloque
                • S'ils utilisent un dossier de bibliothèques de 64 bits, sur un système d'exploitation 32 bits, leur processus se bloque

                  Ceci fait option 1 supérieure à l'option 2.

                  Option 3
                  • non gérés_x32.dll, compilé comme 32 bits
                  • non exploité_x64.dll, compilé 64 bits
                  • dotnet.dll, type CPU de AnyCPU

                    dotnet.dll au moment de l'exécution déterminerait la bi-bie il est exécuté sous, puis clipvoke le correct non gérés.dll.

                    Question (s)
                    1. en tant que développeur de ces bibliothèques, quelle option a le plus de sens?
                    2. En tant que développeur utilisant la bibliothèque Dotnet.dll, quelle option a le plus de sens?
                      1. Pour l'option 3, si vous utilisez dotnet.dll, voudriez-vous savoir que la bibliothèque à l'exécution détermine ce qu'est non géré.dll à utiliser?
                      2. Qu'en est-il de la redistribution de votre application avec ces bibliothèques?
                      3. est une option manquante?


2 commentaires

Suggestion pour le nouveau titre: Quelle est la meilleure façon de prendre en charge plusieurs architectures dans un environnement géré / non géré par mixte?


Choisis la réponse qui répondit le plus pourquoi des questions.


3 Réponses :


2
votes

L'option 3 semble être la plus facile, tandis que l'option 1 semble être la plus sûre. Juste de la perspective de la bibliothèque à appeler, il ne semble pas que ce soit aussi difficile de les gérer que si vous traitez avec un grand nombre d'appels. Le problème principal est que vous allez devoir déclarer une fonction donnée deux fois, en utilisant des noms différents pour les versions 32 et 64 bits, puis modifiez simplement l'attribut dllimport à la cible appropriée. Votre fonction de stub devra décider au moment de l'exécution d'un appel.

Notez que, de côté Logistique, il n'est pas nécessaire d'inclure dans votre dossier de bibliothèque. Tant que vous n'appelez pas un appel à la "mauvaise" bibliothèque, à l'exclusion de cela n'aura aucun impact.


0 commentaires

4
votes

Je choisirais l'option 3, compilez l'ensemble géré pour AnyCPU et nommez les assemblages non gérés pour leur architecture. Je vois deux préoccupations distinctes de cette décision:

Si l'ensemble géré est compilé pour AnyCPU ou une architecture spécifique?

Je pense que les développeurs .NET ne s'attendraient pas à avoir à faire référence à un fichier séparé pour chaque architecture. J'utiliserais AnyCPu pour avoir exactement une DLL.

Les DLL devraient-elles être nommées explicitement pour leur architecture?

Si vous utilisez AnyCPU pour l'assemblage géré, il existe exactement une DLL, il s'agit donc d'un point de théâtre.

Pour l'assemblage non géré, il peut s'attendre à ce que les fichiers compilés pour différentes architectures soient nommés différemment. À partir d'un point de vue technique, nommer les fichiers vous permet de mettre les fichiers pour les deux architectures dans le même répertoire; Cela signifie que vous appelez dans un fichier différent à l'exécution en fonction de l'architecture, mais ce n'est pas un énorme fardeau. Je nommerais les fichiers différemment.


0 commentaires

2
votes

Ce que je fais est ceci:

i ship dotnet.dll compilé pour AnyCPU avec des directives Portable P / Invoke (comme les déclarations de l'API doivent être).

i expédiez non managed_32.bin et non gétionné_64.bin et n'installez que le bon pour l'architecture comme non gérés.dll au moment de l'installation.

Un astuce qui fonctionne toujours serait d'installer non gérés.dll comme:

x86: C: \ Fichiers de programme (x86) \ Fichiers communs \ non gérés.dll. X64: C: \ Fichiers de programme \ Fichiers communs \ non gérés.dll

Si c: \ Program Files \ Les fichiers communs se situent dans le chemin du système, cela entraînera la prise de la DLL correcte automatiquement.


0 commentaires