首先,我要感谢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消息的大小可能会大大减少。
感谢您的任何想法!