Соедините C / C ++ с .NET - PullRequest
       38

Соедините C / C ++ с .NET

4 голосов
/ 13 января 2011

Я подумываю о портировании приложения на C / C ++ в C ++ и CLI.

В основном я хотел бы использовать потенциал рефлексии, сериализации XML и вообще все функции в .NET Framework, предлагаемые Microsoft (возможно, даже в моно).

В рассматриваемом проекте интенсивно не используется STL, а объекты приложения в основном размещаются статически.Много кода написано на C, другой был реализован на C ++.

Проблема в том, что код очень, очень, очень «длинный»: это проблема времени, необходимого для преобразования существующего кода, чтобы он работал правильно.

Я пытался создать проект C ++, скомпилированный с флагом в / clr, в конце концов все было не так плохо.Вы можете сохранить свой существующий код C ++, но в то же время использовать классы «управляемый», даже в состоянии получить доступ к «управляемым» объектам из методов класса C ++.

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

Чтобы воспользоваться преимуществами сериализации данных с использованием отражения, все мои структуры данных должны управляться.Неуправляемый класс не может объявлять поля в соответствии с типом управляемого класса.Чтобы решить эту проблему, если класс преобразован так, что он управляется сборщиком мусора, каждый класс, который объявляет член этого типа, также должен быть управляемым.

С какими трудностями можно столкнуться во время введения управляемых классов?

Ну, я думаю о:

  • Управление строками (я не хочу вызывать AllocaHGlobal дляконвертировать System.String в char * каждый раз, когда мне это нужно (например, в качестве параметра функции)
  • Управление массивами (преобразование классических массивов в cli :: array)
  • (уже упоминалось) смешивание управляемых и неуправляемых классов
  • обработка исключений
  • создание дампа сбоя (ядра) как это влияет
  • ... любая другаячто я еще не думал ...

Ответы [ 2 ]

2 голосов
/ 13 января 2011

Неуправляемые классы могут иметь управляемых членов. Хитрость заключается в использовании шаблона gcroot. Смотри здесь

http://weblogs.asp.net/kennykerr/archive/2005/07/12/Mixing-Native-and-Managed-Types-in-C_2B002B00_.aspx

чтобы узнать больше об этом.

РЕДАКТИРОВАТЬ: в ответ на некоторые другие ваши вопросы: если у вас есть рабочая база кода C ++, которая настолько велика, что вы должны ожидать запросов на изменение из производства, в то время как параллельно вы работаете на порту C ++ / CLI, IMHO лучший подход - избегать двух копий одной и той же кодовой базы. Вместо этого попытайтесь сделать один и тот же код компилируемым как с C ++, так и с C ++ / CLI, используя #ifdef, макросы, генераторы и т. Д. Я знаю, что это возможно, поскольку это именно то, что мы сделали некоторое время назад при переносе программы с ~ 120.000 строки кода.

Для преобразования строк мы использовали этот код:

typedef System::String^ SysString;

inline SysString Std2Sys(const std::string &s)
{
    return gcnew System::String(s.c_str());
}

inline std::string Sys2Std(SysString ss) {
    using namespace System::Runtime::InteropServices;
    const char* chars = 
      (const char*)(Marshal::StringToHGlobalAnsi(ss)).ToPointer();
    std::string s = chars;
    Marshal::FreeHGlobal(System::IntPtr((void*)chars));
    return s;
}

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

1 голос
/ 14 января 2011

Док Браун говорит о gcroot. И наоборот, управляемые классы могут иметь указатели на собственные «подобъекты».

Обычно желательно создавать варианты взаимодействия на auto_ptr или shared_ptr, чтобы компилятор генерировал весь шаблон для отбрасывания подобъектов при смерти родительского объекта, даже с сочетанием управляемого и неуправляемого.

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

...