まず、この投稿について Matt Davis に感謝します。投稿がその特定の質問に対する回答として選択されていないことは知っていますが、投稿は私にとって非常に役に立ちました. いくつかの小さな問題を修正する必要がありました (主に、彼が提供したコードのファイルパスを調整することでした) が、彼の C++ ブリッジ メソッドを使用して、C# WCF サービス用のアンマネージ C++ クライアントを簡単に作成できました。
私は現在、そこに示されている基本的な概念を改善する方法を模索しています。以下は、Matt の投稿にある HelloServiceClientBridge.cpp ファイルのコードの一部です。
String^ message = client->SayHello(gcnew String(name));
client->Close();
IntPtr ptr = Marshal::StringToHGlobalAnsi(message);
rv = std::string(reinterpret_cast<char *>(static_cast<void *>(ptr)));
ここで文字列のコピーが大量に作成されるようです。文字列のコピーが作成される可能性のあるすべての場所を次に示します。
name変数内の文字列の元のアンマネージド コピーgcnew String(name)が呼び出されたときの文字列のマネージド コピー- わかりませんが、マネージド文字列がパラメーターとして
SayHello()メソッドに渡されると、別のコピーが作成される可能性があります - 文字列は、C# サービスに送信される WCF メッセージにコピーされます。
- よくわかりませんが、メッセージを受信したときに C# サービスによって別のコピーが作成される可能性があります
String.Formatが呼び出されると、文字列の別のコピーが作成されると思います- 新しい "Hello" 文字列は、クライアントに送信される WCF メッセージにコピーされます
- よくわかりませんが、メッセージを受信したときに C# クライアントによって別のコピーが作成される可能性があります
- よくわかりませんが、C# クライアントが文字列を C++ ブリッジに返すときに、別のコピーが作成される可能性があります。
Marshal::StringToHGlobalAnsi(message)が呼び出されると、新しい文字列のアンマネージド コピーが作成されます。- よくわかりませんが、文字列が
std::string
アンマネージドおよびマネージドの相互運用性とプロセス間通信を使用している場合、一部のコピーは避けられないことに気付きましたが、このコピーの一部を回避できるかどうか疑問に思っています。単純な HelloWorld 型の例では大したことではありませんが、大量のデータが渡される場合、アンマネージドからマネージドにコピーし、さらにあるプロセスから別のプロセスにコピーするコストは非常に大きくなる可能性があります。したがって、プロセス間通信が行われているのと同時に、管理されていないものから管理されているものへ、および/またはその逆へのマーシャリングを行う方法があるかどうか疑問に思っています。
私が考えた 1 つの可能性は、コードを変更して、アンマネージ文字列からマネージ文字列としてフォーマットされた WCF メッセージに文字列を直接コピーできるようにすることでした。どうせその時点でコピーを作らなければならないので、そのコピーが以前のコピーの機能を兼ねていれば一石二鳥だと思いました。
私が考えたもう 1 つの可能性は、WCF メッセージを介して C++ プロセスから C# サービスにアンマネージド ポインターを渡すことでした。これは、C# サービスによってマネージド文字列にマーシャリングされます。もちろん、これは、メモリの割り当てとそのポインタのメモリの割り当て解除の責任者を特定するのがかなり面倒になる可能性がありますが、コピーが削減され、WCF メッセージのサイズが大幅に削減される可能性があります。
アイデアをお寄せいただきありがとうございます。