在进程跃点期间将非托管转换为托管

时间:2010-01-11 17:43:59

标签: c++ wcf interop unmanaged managed

首先,我要感谢Matt Davis this post。我知道这个帖子没有被选为这个具体问题的答案,但这篇文章对我非常有帮助。我有几个小问题要解决(主要是调整他提供的代码中的文件路径),但我很容易使用他的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类型示例来说,这不是什么大问题,但是如果传递大量数据,从非托管到托管再从一个进程复制到另一个进程的成本可能很高。所以,我想知道是否有办法在进程间通信发生的同时从非托管到托管和/或反之亦然。

我考虑的一个可能性是修改代码,以便可以将字符串从非托管字符串直接复制到格式化为托管字符串的WCF消息中。我想,因为我们不得不在那时制作一份副本,如果该副本还能提供早期副本之一的功能,那将是很好的,所以我们可以一石二鸟。

我考虑的另一种可能性是通过WCF消息将非托管指针从C ++进程传递到C#服务,然后可以通过C#服务将其编组到托管字符串。当然,这可能会非常混乱,弄清楚谁负责分配内存并为该指针释放内存,但复制将减少,WCF消息大小可能会大大减少。

感谢您的任何想法!

1 个答案:

答案 0 :(得分:0)

我已经开始探索WWSAPI作为为WCF服务创建C ++客户端的方法。到目前为止,看起来这个解决方案运作良好。