Quand la CLR V2, la CLR V4 et du code mixte se rencontrent

“Mixed mode assembly is built against version ‘v2.0.50727’ of the runtime and
cannot be loaded in the 4.0 runtime without additional configuration information”

Voici le petit message d’amour que peut vous renvoyez votre ami la CLR lorsque vous
essayez d’exécuter une application qui :

  • référence une assembly mixte (mêlant code natif et code managé) qui a été compilée
    pour être basée sur une version différente de la CLR utilisée par votre point d’entrée.

La solution à ce problème est assez simple, il suffit de rajouter une section dans
votre fichier de config :

<configuration>

<startup useLegacyV2RuntimeActivationPolicy="true">

<supportedRuntime version="v4.0"/>

</startup>

</configuration>

L’attribut useLegacyV2RuntimeActivationPolicy

La clé du problème se situe donc dans l’utilisation de l’attribut useLegacyV2RuntimeActivationPolicy
qui est à false par défaut. Cet attribut permet de changer la politique de chargement
de CLR au sein de votre application. Il y a eu en effet un gros changement à ce sujet
:

  • Dans l’ère pré-CLR V4, en V2 quoi, il n’était possible de charger
    qu’une seule version de CLR au sein d’un process. La politique par défaut était de
    charger toutes vos assemblies en utilisant la version la plus récente de la CLR que
    vous aviez à disposition. Cette stratégie a comme avantage que votre ancien code bénéficie
    automatiquement des améliorations apportées par des versions plus récentes de CLR.
    Mais cela pouvait posait des problèmes de compatibilité dans certains rares cas.
  • Avec la CLR V4, il est à présent de charger différentes versions
    de CLR au sein d’un même process et afin de ne plus être confronté aux problèmes de
    compatibilité la politique de chargement a changé. A présent les assemblies basées
    sur la CLR 4, utilisent la CLR 4, et les autres utilisent la version la plus récente
    inférieure à la V4.

Le problème avec les assemblies mixtes c’est que la CLR doit être capable de savoir
quelle est la CLR a utiliser lorsque un thread natif appel du code managé. Il faut
donc désactiver le side by side afin d’avoir une seule version identifiable.

Mais pourquoi ça marche très bien depuis mes tests unitaires ?

Confronté au problème une de mes premières questions a été de comprendre pourquoi
mon code fonctionne très bien depuis mes tests unitaires alors qu’il plante lorsque
je l’appelle depuis mon application. Le moteur d’exécution des tests unitaires MSTest
est QTAgent.exe (QTAgent32.exe en version 32 bits, et oui VS 2010 supporte enfin l’exécution
de tests unitaires en 32 et 64 bits). Si l’on va farfouiller
un petit peu dans le dossier C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDE
à la recherche des fichiers de configs des tests runners on se rend compte que Microsoft
a configuré le chargement de runtime via le fameux attribut useLegacyV2RuntimeActivationPolicy.

Ce qui veut donc dire que par défaut tous vos tests unitaires utiliseront uniquement
la V4 de la CLR et que le hosting de CLR Side by Side est désactivé pour tous vos
tests unitaires.

 

Une réflexion au sujet de « Quand la CLR V2, la CLR V4 et du code mixte se rencontrent »

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *