C#

Интеграция Native кода в C# проект

Сегодня стала очень популярной платформа .Net Framework и язык C#. На ней пишутся приложения, игры, инструменты. Однако существует много кода написанного на C++, который часто нужно использовать в C# проектах.

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

В этой статье речь пойдет о том, как интегрировать Native код в C# проект и успешно его развивать. В качестве IDE будет использоваться Microsoft Visual Studio.

Настройка проектов


На прямую вызывать C++ код из C# нельзя. Так же нельзя подключить к C# проекту native проект. Поэтому нам понадобится дополнительная прослойка — Managed C++ проект. Этот проект создаст Managed dll, которая будет затем подключена в основное приложение. Смысл этого проекта в том, что он может содержать как managed код так unmanaged код, т.е. код на обычном C++. Более того, он может подключать обычный native проект и использовать его код.

Рассмотрим интеграцию C++ проекта в C# проект на простом примере. Создадим солюшен с Windows Forms проектом. Это будет наше приложение. Нам нужно подключить к нему native проект.

Для начала подключим его к салюшену и укажем чтобы он собирался как Static library. Это можно указать в настройках проекта.



Как уже было сказано, мы не можем напрямую использовать этот код в нашем приложении. Поэтому создадим дополнительный проект, который будет связующим звеном. Создаем его обычными средствами, как простой C++ проект.



При создании проекта указываем, чтобы его код компилировался в dll. Кроме того указываем, чтобы это был пустой проект.


После создания проекта нужно указать что это managed проект. Для этого в его настройках нужно выбрать параметр /crt. Именно этот флаг скажет компилятору, что нужно сделать managed сборку.


В этот проект можно подключать другие managed сборки. Их нужно указать в разделе Reference. В разделе Project Dependencies... выберите native проект, который мы подключили раньше.



Ну и не забудьте подключить Managed C++ проект к C# проекту через Reference. Настройка проекта завершена. Теперь вы можете написать код на Managed C++, который будет использовать С++ код напрямую. Это будет обертка управляемого кода, которую можно будет использовать в C#.

Использование native кода в Managed C++


Класс написанный на Managed C++ может напрямую использовать С++ код. Экземпляр управляемого класса может содержать указатель на не управляемый класс.

// C++
public class Foo
{
public:
  void  Do();
}

// Managed C++
public ref FooWrapper
{
public:
      FooWrapper()
      {
           m_class = new Foo();
      }
      void Shutdown()
      {
           delete( m_class );
      }

      void Do()
      {
           m_class->Do();
      }
private:
      Foo*     m_class;
}

// C#
FooWrapper foo = new FooWrapper();
foo.Do();
foo.Shutdown();

Не забывайте следить за освобождением выделенной памяти. В неуправляемом коде управление памятью ложится на программиста.

Совет: Не стоит делать обертки для всех native классов. Значительно лучше выносить только высоко-уровневые функции, чтобы инкапсулировать всю функциональность в native коде.

Например если это библиотека, которая проводит какие то расчеты и выдает результат, то все это можно оформить в статическую функцию класса.

// Managed C++
public ref FooWrapper
{
public:
      static void Do()
      {
           m_class = new Foo();
           m_class->Do();
           delete( m_class );
      }
}

// C#
FooWrapper.Do();

Отладка


Одной из проблем при разработке приложений является их отладка. По умолчанию нет возможности при отладке спускаться по стеку в native код. Однако можно включить в настройках проекта опцию Enable unmanaged code debugging и при отладке можно будет остановить приложение с просматривать callstack от native кода.



Однако это приведет к некоторому снижению производительности, поэтому имеет смысл создать дополнительную build-конфигурацию и собирать ее в тот момент когда нужно дебажить native код.

Похожие записи




Комментарии (0)

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.

Warning: Unknown: write failed: No space left on device (28) in Unknown on line 0

Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/var/lib/php5) in Unknown on line 0