首先,我要感謝Matt Davis的this post。我知道這個帖子並沒有被選爲這個具體問題的答案,但這個帖子對我非常有幫助。我有幾個小問題需要解決(主要是調整他提供的代碼中的文件路徑),但我很容易使用C++橋接方法爲C#WCF服務創建非託管C++客戶端。將非託管轉換爲託管過程中的託管
我現在正在探索如何改進那裏提出的基本概念。這裏是馬特的後一點從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消息可能會創建另一個副本我不確定,但是另一份可能會被當它接收到消息
- 我認爲當
String.Format
被調用時創建的字符串的另一個副本的C#服務創建 - 新的「你好」的字符串被複制到被髮送到WCF的消息客戶端
- 我不確定,但C#客戶端收到消息時可能創建另一個副本
- 我不確定,但是當C#客戶端將字符串返回給C++時可能會創建另一個副本橋
- 當調用
Marshal::StringToHGlobalAnsi(message)
時創建新字符串的非託管副本 - 我不知道,但是當字符串轉換爲
std::string
現在可能會創建另一個副本,我知道有些複製是不可避免的,當我們正在與非託管工作和互操作管理和進程間通信,但我想知道是否可以避免這種複製。對於一個簡單的HelloWorld類型的例子來說這不是什麼大問題,但是如果傳遞大量數據,從非託管到託管再從一個進程複製到另一個進程的成本可能會很高。所以,我想知道是否有辦法在發生進程間通信的同時從非託管到託管和/或反之亦然。
我考慮過的一種可能性是修改代碼,以便可以將字符串從非託管字符串直接複製到格式爲受管字符串的WCF消息中。我認爲既然我們必須在這一點上做一個副本,那麼如果這個副本也服務於其中一個較早副本的功能將會很好,所以我們可以一石二鳥。
我考慮過的另一種可能性是通過WCF消息將C++進程的非託管指針傳遞給C#服務,然後C#服務可以將這些指針編組爲一個託管字符串。當然,這可能會非常混亂,要弄清楚誰負責分配內存併爲該指針釋放內存,但複製將會減少,並且WCF消息的大小可能會大大減少。
感謝您的任何想法!