2010-01-11 216 views
0

首先,我要感謝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消息的大小可能會大大減少。

感謝您的任何想法!

回答

0

我已經開始探索WWSAPI作爲爲WCF服務創建C++客戶端的一種方法。到目前爲止,它看起來像這個解決方案工作得很好。