2010-01-11 6 views
0

D'abord, je tiens à remercier Matt Davis pour this post. Je sais que le poste n'a pas été choisi comme réponse à cette question spécifique, mais le poste m'a été extrêmement utile. J'ai eu quelques petits problèmes à corriger (principalement en ajustant les chemins de fichiers dans le code qu'il a fourni), mais j'ai facilement pu créer un client C++ non géré pour un service C# WCF en utilisant sa méthode de pont C++. J'explore maintenant comment améliorer les concepts de base présentés ici. Voici un peu de code à partir du fichier HelloServiceClientBridge.cpp dans le poste de Matt:Convert Unmanaged à géré pendant le processus Hop

String^ message = client->SayHello(gcnew String(name)); 
client->Close(); 
IntPtr ptr = Marshal::StringToHGlobalAnsi(message); 
rv = std::string(reinterpret_cast<char *>(static_cast<void *>(ptr))); 

Il semble que beaucoup de copies d'une chaîne vont créer ici. Voici tous les endroits potentiels que je vois où une copie de la chaîne peut être faite:

  • La copie non gérée originale de la chaîne dans la variable name
  • Une gestion copie de la chaîne lorsque gcnew String(name) est invoquée
  • Je ne suis pas sûr, mais une autre copie pourrait être créée lorsque la chaîne géré est passé en paramètre à la méthode SayHello()
  • la chaîne est copiée dans le message WCF qui est envoyé au service C#
  • I » Je ne suis pas sûr, mais autre copie pourrait être créée par le service C# quand il reçoit le message
  • Je pense qu'une autre copie de la chaîne est créée lorsque String.Format est appelé
  • La nouvelle chaîne « Bonjour » est copié dans le message WCF qui est envoyé à la Je ne suis pas sûr, mais une autre copie peut être créée par le client C# lorsqu'il reçoit le message
  • Je ne suis pas sûr, mais une autre copie peut être créée lorsque le client C# renvoie la chaîne au C++ pont
  • Une copie non gérée de la nouvelle chaîne est créée lorsque Marshal::StringToHGlobalAnsi(message) est appelée
  • Je ne suis pas sûr, mais une autre copie pourrait être créée lorsque la chaîne est converti en un std::string

Maintenant, je me rends compte que certains copie est inévitable lorsque nous travaillons avec non géré et géré Interop et de la communication interprocessus , mais je me demande si cette copie pourrait être évitée. Ce n'est pas un gros problème pour un simple exemple de type HelloWorld, mais le coût de la copie de non géré à géré, puis de nouveau d'un processus à un autre peut être significatif si une grande quantité de données a été transmise. Donc, je me demande s'il y a un moyen de faire le marshaling de non géré à géré et/ou vice versa en même temps que la communication interprocess se produit.

Une possibilité que j'ai envisagée était de modifier le code afin que la chaîne puisse être copiée de la chaîne non managée directement dans le message WCF formaté comme une chaîne gérée. Je pensais que puisque nous devions en faire une copie à ce moment-là de toute façon, il serait bon que cette copie serve aussi la fonction de l'une des copies précédentes afin que nous puissions faire d'une pierre deux coups.

Une autre possibilité que j'ai envisagée était de passer un pointeur non géré du processus C++ au service C# à travers le message WCF qui pourrait ensuite être converti en une chaîne gérée par le service C#.Bien sûr, cela risque d'être assez compliqué à déterminer qui est responsable de l'allocation de la mémoire et de libérer la mémoire pour ce pointeur, mais la copie serait réduite et la taille du message WCF pourrait être considérablement réduite.

Merci pour vos idées!

Répondre

0

J'ai commencé à explorer WWSAPI comme un moyen de créer un client C++ pour un service WCF. Jusqu'à présent, il semble que cette solution fonctionne très bien.

Questions connexes