Appelez les fonctions C ++ à partir de C # / .NET

J’ai une solution qui a un projet C ++ et un projet C #.

Le projet C ++ définit une classe que je souhaite instancier en C # et appelle ses fonctions membres. Jusqu’ici j’ai réussi à instancier la classe:

CFoo Bar = new CFoo(); 

Mais quand j’essaie d’appeler une fonction dessus, le compilateur dit que ce n’est pas disponible.

En outre, lorsque j’inspecte l’object dans le débogueur, aucun membre n’est affiché.

Qu’est-ce que j’oublie ici?

Vous devez déclarer la classe dans C ++ / CLI en tant que ref class .

(Notez que nous parlons de C ++ / CLI, pas de C ++. Je suppose que vous devez avoir activé le CLR dans votre projet C ++ CFoo vous ne pourriez pas faire fonctionner le nouveau CFoo .)

Modifier:

Vous n’avez pas besoin de convertir toutes vos anciennes classes en classes de ref .

Supposons que vous ayez un vieux C ++:

 class FooUnmanaged { int x; FooUnmanaged() : x(5) {} }; 

Ensuite, vous essayez de l’envelopper dans une classe CLR:

 ref class FooManaged { FooUnmanaged m; }; 

Comme vous l’avez remarqué, vous obtenez une erreur en disant que cela n’est pas autorisé. Mais essayez ceci:

 ref class FooManaged { FooUnmanaged *m; }; 

C’est parfaitement OK. Le compilateur ne veut pas allouer une instance d’object non géré incorporé à l’intérieur d’un object sur le segment de mémoire géré, mais il est plutôt heureux de disposer d’un pointeur qu’il transforme en System.IntPtr dans l’IL résultant.

Cela signifie que vous devez décider comment appeler delete . La solution la plus probable est:

 ref class FooManaged { FooUnmanaged *u; public: FooManaged(FooUnmanaged *u_) : u(u_) { } ~FooManaged() { delete u; } }; 

Tout comme dans n’importe quelle autre classe C ++. Il est possible que C ++ / CLI puisse faire cette traduction automatiquement pour nous dans une version ultérieure.

Notez que l’IL résultant est que la classe FooManaged implémente désormais IDisposable et que le destructeur a été transformé en une méthode Dispose . Cela permet aux clients .NET de le désallouer correctement, par exemple en C #.

 using (var m = new FooManaged()) { // end of block: m will be disposed (and so FooUnmanaged will be deleted) }