Traducteur de C# à C++ : Opérations sur le code source

Au premier abord, il peut sembler que le traducteur n'ait qu'une seule façon de l'utiliser : en lui fournissant du code C#, nous nous attendons à obtenir en sortie un code C++ équivalent. En effet, cette méthode est la plus courante, mais elle est loin d'être la seule. Voici d'autres modes fournis par le cadre de traduction de code et les utilitaires associés.

Analyse du code C# pour la traductibilité

Les produits sont développés par des programmeurs qui doivent apprendre les détails de la procédure de traduction du code dans d'autres langues et les limitations associées. En conséquence, des situations surviennent lorsque des modifications correctes du point de vue du C# effectuées par les développeurs de produits interrompent le processus de publication pour d'autres langues.
Pendant le développement du projet, nous avons essayé plusieurs méthodes pour automatiser la détection de tels problèmes :

  1. Le problème peut être détecté lors de la traduction du code C# en C++, de la construction du code C++ traduit ou de l'exécution des tests. C'est le pire cas possible puisque les problèmes sont détectés après la fusion du code dans la branche principale, souvent – avant la publication. De plus, le problème est résolu par des personnes qui ne sont pas au courant des changements qui l'ont causé, ce qui augmente le temps pour l'éliminer.
  2. Le problème peut être détecté dans l'environnement CI. Ainsi, les développeurs C# apprennent le problème avant la fusion dans la branche commune ou après une telle fusion, selon les pratiques adoptées par une équipe particulière. Cela augmente la rapidité de résolution des problèmes mais nécessite la programmation de vérifications supplémentaires dans l'infrastructure du traducteur ou des utilitaires tiers.
  3. Le problème peut être détecté localement par le développeur C# lors de l'exécution d'outils spécialisés – par exemple, le traducteur en mode analyseur. C'est pratique mais nécessite le développement d'utilitaires supplémentaires et de la discipline.

Abaissement de la version du langage C#

Limiter la version du langage C# nécessite de la discipline de la part des programmeurs C# et est souvent peu pratique. Pour contourner ces limitations, la traduction peut se faire en deux étapes : d'abord, remplacer les constructions des versions modernes du langage C# par des analogues pris en charge des normes passées, puis procéder directement à la traduction.
Lors de l'utilisation d'un traducteur basé sur un analyseur obsolète, l'abaissement ne peut être effectué qu'à l'aide d'outils externes (par exemple, des utilitaires écrits sur la base de Roslyn). D'autre part, les traducteurs basés sur Roslyn effectuent les deux étapes séquentiellement, ce qui permet d'utiliser le même code à la fois lors de la traduction par eux et lors de la préparation du code pour la traduction par des outils plus anciens.

Préparation d'exemples d'utilisation de bibliothèques converties

Cela est similaire à la traduction du code produit mais implique des exigences quelque peu différentes. Lors de la traduction d'une bibliothèque de dizaines de millions de lignes, il est important, avant tout, de suivre le comportement du code C# original aussi strictement que possible, même au détriment de la lisibilité – un code plus simple mais aux effets différents devra être débogué plus longtemps. D'autre part, les exemples d'utilisation du code traduit doivent paraître aussi simples que possible, rendant clair comment utiliser le code en C++, même s'il ne correspond pas au comportement des exemples originaux écrits en C#.
Par exemple, lors de la création d'objets temporaires, les programmeurs C# utilisent souvent l'instruction using pour éviter les fuites de ressources et fixer strictement le moment de leur libération, sans compter sur le GC. Une traduction stricte de using donne un code C++ assez complexe en raison des nombreuses nuances du genre "si une exception est lancée dans le bloc de l'instruction using, et que Dispose() lance également une exception, laquelle se retrouve dans le contexte de capture ?". Un tel code ne ferait que tromper le programmeur C++, créant l'impression que l'utilisation de la bibliothèque est difficile, mais en réalité, il suffit d'avoir un pointeur intelligent sur la pile, qui au bon moment supprime l'objet et libère les ressources.

Préparation de la documentation pour le code

Les bibliothèques qui fournissent une API peuvent être documentées par des commentaires XML conformément aux pratiques C#. Transférer ces commentaires en C++, par exemple au format Doxygen, n'est pas une tâche triviale. En plus du balisage, il est nécessaire de remplacer les références aux types (puisque en C# les noms complets sont écrits avec un point, en C++ avec une paire de deux-points), leurs membres, et, dans le cas de l'utilisation de propriétés, comprendre également s'il s'agit d'un accesseur ou d'un mutateur. De plus, il faut traduire les fragments de code qui sont dépourvus de sémantique et peuvent être incomplets.
Cette tâche est résolue à la fois par les moyens du traducteur lui-même et par des utilitaires externes, par exemple en analysant la documentation XML générée et en préparant des fragments supplémentaires, tels que des exemples d'utilisation des méthodes.

Conclusion

Comme nous pouvons le voir, un cadre professionnel pour la conversion de code, en plus d'une traduction de haute qualité du code C# en C++, devrait être capable de déterminer la traductibilité du code source, d'abaisser la version du langage si nécessaire, de traduire des exemples d'utilisation des bibliothèques converties et leur documentation.

Articles liés :