Бэкэнд C ++ с внешним интерфейсом C #? - PullRequest
9 голосов
/ 30 октября 2010

У меня есть проект, в котором мне придется обрабатывать 100 с, если не 1000 с сообщений в секунду, и обрабатывать / отображать эти данные соответственно на графиках (пользователь будет искать набор данных, в котором график будет отображаться вв реальном времени, не буквально располагая тысячи значений на графике).

У меня возникают проблемы с пониманием использования dll для обработки основной массы сообщений в C ++, но затем передачи информации в интерфейс C #.Может ли кто-нибудь придумать это для меня здесь?

Кроме того, поскольку скорость будет приоритетом, мне было интересно, если доступ к двум различным уровням кода будет иметь большее снижение производительности, чем программирование проекта полностью на C # или, конечно, на C ++, хотя я читалплохие вещи в программировании графического интерфейса на C ++, в котором это приложение должно выглядеть современно, чисто, профессионально и т. д., поэтому я подумал, что C # будет шагом вперед (возможно, XAML, wPF)

Спасибо за ваше время

Ответы [ 5 ]

7 голосов
/ 30 октября 2010

Самый простой способ взаимодействия между C / C ++ DLL и сборкой .NET - через p / invoke. На стороне C / C ++ создайте DLL, как и любую другую. На стороне C # вы создаете объявление p / invoke. Например, скажите, что ваша DLL - mydll.dll, и она экспортирует метод void Foo():

[DllImport("mydll.dll")]
extern static void Foo();

Вот и все. Вы просто вызываете Foo, как и любой другой метод статического класса. Сложная часть - сбор данных, и это сложный вопрос. Если вы пишете DLL, вы, вероятно, можете сделать все возможное, чтобы упростить функции экспорта. Подробнее о p / invoke marshalling смотрите здесь: http://msdn.microsoft.com/en-us/magazine/cc164123.aspx.

Вы получите удар по производительности при использовании p / invoke. Каждый раз, когда управляемое приложение выполняет неуправляемый вызов метода, оно выполняет удар, пересекающий управляемую / неуправляемую границу, а затем снова возвращается. Когда вы собираете данные, происходит большое копирование. При необходимости копирование может быть уменьшено с помощью «небезопасного» кода C # (с помощью указателей для прямого доступа к неуправляемой памяти).

Что вам следует знать, так это то, что все .NET-приложения переполнены вызовами p / invoke. Ни одно приложение .NET не может избежать вызовов операционной системы, и каждый вызов ОС должен попадать в неуправляемый мир ОС. WinForms и даже приложения WPF GUI совершают этот путь много сотен, даже тысячи раз в секунду.

Если бы это было моей задачей, я бы сначала сделал это на 100% в C #. Затем я бы профилировал и настроил производительность по мере необходимости.

6 голосов
/ 30 октября 2010

Если скорость является вашим приоритетом, C ++ может быть лучшим выбором.Попытайтесь сделать некоторые оценки о том, насколько сложен на самом деле расчет (1000 сообщений могут быть тривиальными для обработки в C #, если вычисление для каждого сообщения легко, и они могут быть слишком сложными даже для самой оптимизированной программы).C ++ может иметь некоторые преимущества (в отношении производительности) по сравнению с C #, если ваши алгоритмы сложны, включают разные классы и т. Д.

Возможно, вы захотите взглянуть на этот вопрос для сравнения производительности.

Хорошая идея - разделить заднюю часть и переднюю часть.Если вы получаете снижение производительности из-за наличия одного в C ++ и C #, это зависит от того, какой объем данных на самом деле необходим.

Я не думаю, что программирование с графическим интерфейсом является болью в целом.MFC может быть болезненным, Qt нет (ИМХО).

Может быть, это даст вам несколько очков для начала!

4 голосов
/ 30 октября 2010

Другой возможный путь: звучит так, будто это задание - главная цель для распараллеливания.Создайте свое приложение таким образом, чтобы оно могло распределить рабочую нагрузку на несколько процессорных ядер или даже на разных компьютерах.Тогда вы сможете решить свои проблемы с производительностью (если они будут), выбрасывая на них аппаратное обеспечение.

2 голосов
/ 30 октября 2010

Если у вас есть исходный код C / C ++, рассмотрите возможность его связывания с C ++ / CLI .NET Assembly.Этот вид проекта позволяет смешивать неуправляемый код и помещать в него управляемые интерфейсы.В результате получается простая сборка .NET, тривиальная для использования в проектах C # или VB.NET.

Существует встроенный маршалинг простых типов, так что вы можете вызывать функции со стороны управляемого C ++ в неуправляемыйбоковая сторона.

Единственное, что вам нужно знать, это то, что когда вы делегируете делегат в указатель на функцию, он не содержит ссылку, поэтому, если вам нужен C ++ для хранения управляемых обратных вызовов, вам нужноорганизовать ссылку для проведения.Кроме этого, большинство встроенных конверсий работают как положено.Visual Studio даже позволит вам отлаживать через границу (включить неуправляемую отладку).

Если у вас есть .lib, вы можете использовать его в проекте C ++ / CLI, если он связан с C-Runtimeдинамически.

1 голос
/ 30 октября 2010

Вы должны действительно создать этот прототип на C #, прежде чем начинать разбирать и сортировать данные в небезопасных структурах, чтобы можно было вызывать функции в C ++ DLL.C # очень часто быстрее, чем вы думаете.Прототипирование дешево.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...