2010-01-11 219 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++客户端的一种方法。到目前为止,它看起来像这个解决方案工作得很好。