Guide du C++ pour .NET Programmation
= L'absence des char* =
Les chaînes de caractères sont très utilisées en C++, mais inexistantes en.
NET.
Il existe pour cela la classe String, qui doit remplacer l'utilisation des char*.
Des méthodes de conversion de l'un à l'autre sont donc disponibles, notamment grâce à la classe Marshal.
Ces méthodes étant statiques, leur appel est assez pénible à taper et surtout peu lisible, surtout si la tâche est très répétitive.
Les paragraphes suivants proposeront donc de créer des MACROS pour rendre votre code bien plus lisible.
On notera que cela n'est faisable qu'en C++ pour.
NET, et pas en C# car ce dernier langage est dépourvu de macro (en C# la classe Marshal est bien sûr toujours utilisable).
Conversion des char* en String*.
La méthode statique PtrToStringAnsi de la classe Marshal va réaliser la conversion d'un char * en String *.
Le code suivant en est un exemple, (la valeur 256 correspond à la taille maximale de votre chaîne initiale, vous pouvez modifier ce paramètre):
 using namespace System::Runtime::InteropServices;
 char* ch_1 = "Hello World !";
 String* ch_2 = Marshal::PtrToStringAnsi(IntPtr((void*) ch_1 ) , 256);
Il est fortement conseillé de créer une Macro dans un fichier "header" :
 #define CONVERT2STRING(x) Marshal::PtrToStringAnsi(IntPtr((void*) x ),256)
Ainsi l'utilisation de la classe Marshal est simplifiée
 using namespace System::Runtime::InteropServices;
 char* ch_1 = "Hello World !";
 String* ch_2 = CONVERT2STRING(ch_1);
Conversion des String* en char*.
De même, La méthode statique StringToHGlobalAnsi de la classe Marshal va réaliser la conversion d'un String * en char *.
Cet appel nécessite une libération en utilisant la méthode "FreeHGlobal".
 using namespace System::Runtime::InteropServices;
 String* s = new String("hello, World");
 const char* temp = (const char*)(Marshal::StringToHGlobalAnsi(s).ToPointer());
 Marshal::FreeHGlobal(IntPtr((void*)temp));
De la même façon que précédemment, on pourra créer des macros :
 // creation
 #define CONVERT2CHAR(x) (char*)(Marshal::StringToHGlobalAnsi(x).ToPointer())
 // libération
 #define FREECHAR(x) Marshal::FreeHGlobal(IntPtr((void*) x ));
et les utiliser ainsi :
 using namespace System::Runtime::InterropServices;
 String* ch_1;
 // allocation en mémoire
 char* ch_2 = CONVERT2CHAR(ch_1);

// libération de la mémoire
 FREECHAR(ch_2);
= Les structures de données .NET ou non =
Les structures « non gérées » (ou en franglais « non managées ») sont du domaine du C++ classique, donc sans plate-forme .NET, et donc inaccessibles à
partir de classes C#.
Les structures « gérées » (ou en franglais « managées »), quant à elles, sont des éléments qui pourront être accessibles.
Le C++ pour .NET permet une utilisation des deux types de structures de données. Il est donc nécessaire dans ce
langage de déclarer explicitement qui est géré et qui ne l'est pas, grâce aux mots-clé __gc et __nogc.
Déclarer une classe __gc ou __nogc.
Une classe « gérée » sera déclarée ainsi :
 public __gc class MaClasseGeree {
De même pour une classe « non gérée » :
 public __nogc class MaClasseNonGeree {
Déclarer un enum __gc ou ___nogc.
De la même manière on déclare un type énuméré avec __gc pour « géré » et __nogc pour « non géré »:
 public __gc enum Couleur = { ROUGE, ORANGE, VERT };
Déclarer un tableau __gc ou __nogc.
De la même manière on déclare un tableau avec __gc pour « géré » et __nogc pour « non géré »:
 public String __gc[3] CouleursList = { "Rouge", "Orange", "Vert" };
= Les bibliothèques .NET ou non =
L'ordre d'inclusion des bibliothèques "(libraries)".
Quelques ambiguïtés malheureuses peuvent apparaître si le principe suivant n'est pas respecté :
l'inclusion des fichiers "header" « non gérés » est PRIORITAIRE
Sinon vous risquez de voir apparaître des erreurs au milieu de fichiers sources inconnus, dont la
signification est incohérente.
Par exemple, un cas récurrent comme l'inclusion de codice_1 peut poser ce genre de problème.
Pour éclaircir votre code et éviter cette erreur, il est conseillé de créer un fichier "header" uniquement dédié à
réaliser les inclusions dans le bon ordre.
Par exemple :
 // inclusion_propre.h
 #pragma once
 // inclusions non gérées
 #include <cstring>
 #include "la_vieille_bibliothèque.h"
 // inclusions d'espaces de nom .NET
 using System::Text;
 using System::Runtime::InteopServices;
 // inclusion de fichier headers gérés
 #include "mes_types_geres.h"
 #include "mes_constantes.h"
Ainsi chaque fichier .cpp pourra inclure uniquement ce dernier fichier "header",
à condition que celui-ci soit toujours mis à jour.
Exemple :
 // .cpp
 #include "inclusion_propre.h"
 MaClasseGeree::FonctionTresUtile() {
Pour plus d'information à propos de cette bizarrerie, voir le document correspondant dans la MSDN