Во-первых, я хочу поблагодарить Мэтта Дэвиса за this post. Я знаю, что пост не был выбран в качестве ответа на этот конкретный вопрос, но почта была очень полезна для меня. У меня было несколько небольших проблем для исправления (в основном, для настройки файлов в коде, который он предоставил), но я легко мог создать неуправляемый клиент C++ для службы C# WCF, используя свой метод моста C++.Преобразование неуправляемого в управляемый во время процесса Hop
Теперь я изучаю, как улучшить базовые концепции, представленные там. Вот фрагмент кода из файла 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()
метода - строка копируется в сообщение WCF, который отправляется на C# службы
- I» не уверен, но другой экземпляр может быть создан C# службы, когда он получает сообщение
- Я думаю, еще одна копия строки создается, когда
String.Format
называется - Новый «Hello» строка копируется в сообщение WCF, который посылается на клиент
- Я не уверен, но другой экземпляр может быть создан клиентом C#, когда он получает сообщение
- Я не уверен, но другая копия может быть создана, когда клиент C# возвращает строку в C++ bridge
- Неуправляемая копия новой строки создается при вызове
Marshal::StringToHGlobalAnsi(message)
- Я не уверен, но еще одна копия может быть создана, когда строка преобразуется в
std::string
Теперь я понимаю, что некоторые копирования неизбежны, когда мы работаем с неуправляемым и управляется Interop и межпроцессного , но мне интересно, можно ли избежать этого копирования. Это не имеет большого значения для простого примера типа HelloWorld, но стоимость копирования из неуправляемого в управляемый, а затем снова из одного процесса в другой процесс может быть значительным, если передается большое количество данных. Итак, мне интересно, есть ли способ сделать маршаллинг от неуправляемого до управляемого и/или наоборот, в то же время, что происходит межпроцессное общение.
Одна из возможностей, которую я рассматривал, заключалась в изменении кода, чтобы строка могла быть скопирована из неуправляемой строки непосредственно в сообщение WCF, отформатированное как управляемая строка. Я думал, так как мы должны сделать копию в этом пункте, было бы хорошо, если бы эта копия также служила функции одной из ранних копий, чтобы мы могли убить двух зайцев одним выстрелом.
Еще одна возможность, которую я рассматривал, заключалась в передаче неуправляемого указателя из процесса C++ в службу C# через сообщение WCF, которое затем можно было перевести в управляемую строку службой C#.Конечно, это может быть довольно грязным, выясняя, кто несет ответственность за выделение памяти и освобождение памяти для этого указателя, но копирование будет уменьшено, а размер сообщения WCF может быть значительно уменьшен.
Спасибо за любые идеи, которые у вас могут быть!