Подтвердить что ты не робот

Объединение С++ и С#

Хорошо ли комбинировать С++ и С# или создавать какие-либо проблемы?

У меня есть приложение, для которого некоторые части должны быть С++, а некоторые части - С# (для повышения эффективности). Каким будет лучший способ добиться использования родной С++ dll в С#?

4b9b3361

Ответ 1

Да, использование С# и С++ для вашего продукта очень распространено и хорошая идея.

Иногда вы можете использовать управляемый С++, и в этом случае вы можете использовать управляемый С++-модуль, как и любой другой .NET-модуль.

Обычно вы делаете все, что можете, на С#. Для частей, которые вам нужно сделать на С++, вы обычно создаете С++ DLL, а затем вызываете в эту DLL из С#. Марширование параметров выполняется автоматически для вас.

Вот пример импорта функции C внутри DLL в С#:

[DllImport("user32", CharSet=CharSet.Auto, SetLastError=true)]
internal static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount);

Ответ 2

Вопрос заключается в том, как интегрировать свой собственный код на С++ в свое решение С#, а не только для какого атрибута использовать для вызова существующей функции из win32 API. Даже если ответ был уже принят, я считаю, что он неполный, и должно применяться следующее.

Да, это обычная практика в тех случаях, когда задача может работать быстрее, использовать меньше ресурсов, а также в некоторых случаях обращаться к методам, недоступным в .NET Framework.

Если ваша цель - повысить эффективность, вам нужно закодировать собственную неуправляемую библиотеку С++, вы создадите новый неуправляемый проект С++ (который компилируется как библиотека dll) в визуальной студии и ссылайтесь на эту библиотеку из вашего проекта С#.

В вашем случае кажется, что вы можете писать неуправляемую библиотеку С++, и применяется следующее.

Что касается любых актуальных вопросов, о которых вы спрашивали о, это повлияет на развертывание и обфускацию.

  • Развертывание: имейте в виду, что созданные вами DLL файлы С# будут выполняться на любом CPU, как 32, так и 64 бит, но этот новый собственная и неуправляемая библиотека С++ заставьте свою программу 32 или 64.

    Это то, что вы настроите в диспетчере конфигурации Visual Studio и будут учтены при компиляции вы выберете AnyCPU для С# сборки и для вашей новой неуправляемой библиотеки С++, которая будет в ней собственного проекта, у вас будет для выбора из win32 или x64.

    Итак, теперь у вас будет 2 установки, это Рекомендуемая практика отдельные настройки, один для 32 и другой для 64. Или, поскольку 32 бит поддержка снижается очень быстро, вы может сосредоточиться только на 64-битной версии.

    Кроме того, ваша библиотека может в конечном итоге ссылаться на VС++ redistibutable, предоставленную Visual Studio, которую вы, возможно, придется включать в развертывание, хотя какая-то ее версия включена во многие ОС, я обнаружил, что она редко совпадает с той, которую я скомпилировал с помощью и лучше всего развернуть его с вашим приложением, чтобы быть уверенным. Если этот пакет отсутствует, целевой компьютер будет иметь исключение SideBySide в журнале событий eventviewer > .

    Чтобы поймать и обработать исключение, выведенное из неуправляемого кода, единственный улов, который работает, является пустым, а тот, который не имеет типа исключения в скобках после catch(). Таким образом, вы можете обернуть свои вызовы неуправляемому коду в этом, чтобы обрабатывать все неуправляемые исключения, вызванные из неуправляемого кода, если вы поместите тип .net типа catch (Exception), он просто перепрыгнет через него. Единственный способ поймать неуправляемое исключение, внутри управляемого кода - в этом формате.

<Предварительно > try { //call unmanaged code } catch { //handle unmanaged exception }

  • Обфускация: любые вызовы методов, выполняемые с С#, которые теперь вызывают неуправляемый код теперь будет исключен от переименования автоматически. И с другой стороны, если вам нужна неуправляемая библиотека С++ вызывать методы из вашего управляемого сборок, они должны быть исключено из переименования, вручную, чтобы быть видимый для вызова библиотеки С++ их.

Если вам нужно только вызывать хорошо известные библиотеки С++, такие как Windows, вам не нужно будет создавать новый неуправляемый проект С++, используйте только атрибут [DllImport()], предложенный в предыдущем ответе. И в этом случае вы можете взглянуть на эту ссылку http://www.pinvoke.net/

Ответ 3

Дополнительная информация о различиях С# и С++ и возможностях их слияния:

  • С# - интерпретируемый, как Java. С++ скомпилирован в родной двоичный файл. Это приводит к нескольким различиям, объясняемым далее в следующих пунктах.
  • Совместимость с платформой: С#, как интерпретируемый и продукт Microsoft, отлично работает на Windows, правильно на Linux благодаря отличному проекту Mono, но не так хорошо (или вообще не на всех) на других платформах (Android, IOS, другие.) Если вы хотите написать программное обеспечение для встроенных приложений, где нет поддержки операционной системы, или для написания самой ОС, вы в основном "не можете" использовать С#. С++ полностью кросс-платформенный, как только у вас есть компилятор (что обычно бывает).
  • Интерпретированный код обычно на порядок медленнее, чем двоичный код [1]. Вот почему вы будете использовать С++.
  • Двоичный или промежуточный код: Промежуточный код работает на любом интерпретаторе, доступном в определенной архитектуре, С++ требует перекомпиляции для каждой архитектуры.
  • Кривая обучения: разработчик должен изучать несколько языков, что увеличивает время обучения. Кроме того, труднее найти экспертов на обоих языках.
  • IDE: для С++ любого текстового редактора достаточно, для С# вам в основном требуется определенная среда IDE.
  • В режиме реального времени: Кажется, трудно представить условия в реальном времени с С#.
  • Некоторые сертификаты качества могут быть недоступны для кода С# (критическое программное обеспечение).

Можно ли их комбинировать?

Вероятно, это зависит от вашего проекта. Для большой разработки HMI в Windows это, скорее всего, улучшит ваше время разработки. Но другие требования к программному обеспечению могут ограничивать вас только С++.


[1] Я читал много раз, что интерпретируемый код в некоторых случаях даже быстрее, чем двоичный код, это связано с неправильным представлением: Интерпретатор реализует несколько функций для удобства, поэтому при вызове (например,) sort() в действительности он вызывает двоичную реализацию этой функции. Если эта функция хорошо оптимизирована, последнее время может быть быстрее, но только потому, что все запущенные в двоичном и интерпретируемом компонентах минимальны по сравнению со всем временем, необходимым для сортировки. С другой стороны, если вы кодируете полную логику на обоих языках, бинарная версия всегда будет значительно быстрее. Причина проста: интерпретатор IS - это двоичный код, который запускает, помимо вашего кода, все языковые рамки.