У нас есть монолитное приложение с графическим интерфейсом пользователя MFC, которое на C++ подходит к концу. Мы планируем создать новую функциональность на C# и передавать данные между каждым приложением.
Вопрос: как лучше всего передавать данные между C++ и C#?
Примечания:
Оба конца будут иметь интерфейс с графическим интерфейсом и, вероятно, должны будут передавать только простые данные, такие как Id, и, возможно, иметь механизм, который указывает другому приложению, какой процесс / функциональность использовать.
Например, одним из приложений будет CRM-система на C#, которая при двойном щелчке по строке в сетке будет передавать, скажем, customerId и сообщение для открытия этого клиента в форме клиента приложения MFC.
Я провел небольшое исследование, варианты вроде Windows Messaging, Memory Mapping, Named Pipes или что-то вроде Windows Sockets. На данном этапе мы склоняемся к именованным каналам, но были бы очень признательны за другие советы или подсказки или опыт других людей.





Вы также можете использовать P / Invoke с управляемой стороны - это было бы полезно, если в приложении MFC есть C API. Также вы можете использовать COM с любой стороны.
Перечисленные вами параметры, безусловно, действительны, но вы также можете рассмотреть COM.
@Shaun Austin: На самом деле я имел в виду COM :), поэтому я сказал COM.
Мой плохой, извините, давно забыл о том, что COM EXE-файлы вышли из строя! смущенный
Не волнуйтесь, ваша репутация не запятнана, рядом с комментарием нет стрелок [] -]
Лично я бы подумал об использовании чего-то вроде именованных каналов, поскольку они просты в использовании со стороны C++, а также System.IO.Pipes со стороны .NET.
Это также будет путь наименьшего сопротивления, если вы планируете со временем заменить другие части приложения, не относящиеся к .NET.
Обратите внимание, что начиная с .NET 2.0 именованные каналы поддерживаются через пространство имен <code> System.IO.Pipes </code>. Нет необходимости в DllImports.
Сделайте ваш выбор:
Почему именованные каналы?
В .Net просто используйте System.IO.Pipes.
В C++ используйте CreateNamedPipe и CreateFile.
Не файл! У меня не было ничего, кроме проблем с работой в системах, где он записывает в файл в одной программе и (посредством опроса) считывает изменения в другой программе.
Ах да, но, конечно, вы можете создать другой файл, чтобы первый файл знал, что вы закончили работу с ним. Шучу :) Это просто вариант, а не рекомендуемый :)
Нет просто переименовать / удалить / переместить файл! Файл уже используется? Просто зацикливайтесь и продолжайте попытки! АААА! :)
На самом деле это можно было сделать довольно чисто. Зарегистрируйтесь для получения уведомлений файловой системы. Скажем, программа A использует file.p1, когда использует его, и переименовывает его в .avail, когда это не так. Программа 2 регистрирует уведомления файловой системы для файла .avail.
... Когда программа 2 использует его, она использует file.p2. Затем каждая программа может реализовать очередь данных, ожидающих перехода в файл.
передача файлов - это широко используемый механизм, вы пишете файл для каждого сообщения / транзакции, а другое приложение ожидает уведомления об изменении каталога, чтобы прочитать его. Это очень легко сделать, но лучше для сторонней связи.
ya есть миллион способов сделать это.
Я бы использовал сокеты (TCP) - и MFC, и .NET имеют прямую поддержку для них.
Я бы выбрал стандартные оконные сообщения (например, WM_FOO) или DCOM:
Сообщения будут работать до тех пор, пока связь очень проста, а накладные расходы на ее настройку минимальны. Если вы можете свести общение к одному или двум целым числам на сообщение, это, вероятно, будет хорошим местом для начала. Если оба приложения уже являются оконными приложениями, у них обоих уже есть петли сообщений, так что вы уже почти на своем пути.
DCOM требует гораздо больше накладных расходов программиста, но это приятно тем, что вы можете определить более богатый интерфейс и избежать необходимости преобразовывать сложные сообщения в / из двоичной формы. Если вы пойдете по этому пути, CoRegisterClassObject станет отправной точкой для публикации объекта через DCOM. Я никогда не пробовал делать это из приложения на C#, но в принципе это должно быть вполне возможно.
Вам действительно нужны два процесса?
Неуправляемый код C++ и управляемый код C# вполне могут работать в одном процессе, и с небольшим уровнем управляемого C++ / CLI вы можете заменить сложность межпроцессного взаимодействия простыми вызовами функций.
Предполагая, что у вас есть исходный код для устаревшего приложения, посмотрите, не можете ли вы скомпилировать весь код «рабочей лошадки» как DLL, а затем вызвать оттуда отдельные функции / окна. После того, как вы это заработаете, вы можете просто написать управляемые оболочки C++ вокруг необходимых вам функций и вызывать их из вашего кода C#. Если повезет, на весь процесс уйдет меньше суток.
Я бы сказал C++ / CLI, если вам не нужно беспокоиться о платформе .NET, существующей во всех системах, на которых будет работать приложение, и о COM в противном случае. Однако это действительно будет зависеть от того, что вам наиболее удобно и с чем вы знакомы. Мне нравится существующая структура «вызова функций» C++ / CLI и COM (в отличие от построения ее с помощью других протоколов), но это только мне.
В настоящее время я использую COM для добавления некоторых функций компонента .NET, в основном из-за необходимости по-прежнему работать с резервными вариантами, если .NET отсутствует, но это относится к моим потребностям, когда предпочтительнее максимальное развертывание.
Подойдет либо COM, либо DCOM - в зависимости от того, работает ли приложение на одном компьютере или нет.