Я бы хотел взять пошаговое
подход, где мы медленно перемещаем порции
кода
Это единственный реалистичный способ сделать это.
Во-первых, какой тип управления версиями вы используете? (Если вы используете ветвление контроля версий, которое позволяет вам проводить эксперименты и видеть, что работает, минимизируя риск компрометации вашего кода; другие тоже в порядке, но вам придется быть очень осторожным в зависимости от того, что вы используете).
Редактировать : Я только что видел, что вы используете SVN. Возможно, стоит перейти на mercurial или git, если вы можете это сделать (изменение обеспечивает качественный скачок в том, что вы можете сделать с помощью базы кода).
и писать новые функции в C # для
пример и скомпилировать это в
библиотека или DLL, на которые можно ссылаться
из устаревшего приложения.
Это ... не обязательно хорошая идея. Код C # может предоставлять COM-интерфейсы, доступные в C ++. Написание клиентского кода на C ++ для модулей, написанных на C #, может быть забавным, но вы можете счесть это обременительным (с точки зрения соотношения усилий и выгод); Он также медленный и подвержен ошибкам (по сравнению с написанием клиентского кода C # для модулей, написанных на C ++).
Лучше подумать о создании каркаса приложения на C # и использовании модулей (уже) написанных на C ++ для основной функциональности.
Возможно ли это и что лучше?
способ сделать это?
Да, это возможно.
Сколько человек вовлечено в проект?
Если их много, лучшим способом было бы сделать несколько (два? Четыре?) Работ над новой структурой приложения, а остальные продолжить как обычно.
Если их мало, вы можете подумать о том, чтобы этим руководил либо человек, либо работающий неполный рабочий день.
Процент людей / усилий, назначенных для каждого (поддержка старого кода и разработка нового кода), должен зависеть от размера команды и ваших приоритетов (Является ли переход проблемой с низким приоритетом? дата?)
Лучший способ сделать это - начать адаптировать модули кода, чтобы их можно было использовать в нескольких сценариях (как со старым, так и с новым кодом), и продолжить разработку параллельно (опять же, это будет значительно облегчено при использовании разветвленная распределенная система контроля версий).
Вот как мне это сделать (итеративная разработка, с небольшими шагами и большим количеством проверок правильности между ними):
Выберите функциональный модуль (который не связан с GUI) в старой кодовой базе.
Удалите ссылки на код MFC (и другие библиотеки, недоступные в VS2010 Express - как ATL) из модуля, выбранного на шаге 1.
Не пытайтесь переписать функциональность MFC / ATL с помощью пользовательского кода, за исключением небольших изменений (т. Е. Невозможно создать собственную структуру GUI, но можно решить написать собственный указатель интерфейса COM обертка похожа на CComPtr ATL).
Если код сильно зависит от библиотеки, лучше разделить его как можно больше, а затем пометить, чтобы он был переписан в будущем с использованием новых технологий. В любом случае, для библиотеки, сильно зависящей от MFC, лучше переписать код, используя что-то еще (C #?).
максимально уменьшите связь с выбранным модулем (убедитесь, что код находится в отдельной библиотеке, четко определите, какие функции модуль предоставляет клиентскому коду) и получите доступ к функциям с разделителями только через определенный открытый интерфейс ( в старом коде).
Убедитесь, что база старого кода по-прежнему работает с модифицированным модулем ( test - в конечном итоге автоматизируйте тестирование для этого модуля ) - это важно , если вам нужно оставайтесь на рынке, пока не отправите новую версию.
Поддерживая текущее приложение, запустите новый проект (на C #?), Который реализует графический интерфейс и другие компоненты, которые необходимо модернизировать (например, компоненты, сильно зависящие от MFC). Это должно быть тонкослойное приложение, предпочтительно не зависящее от бизнес-логики (которое должно как можно больше оставаться в унаследованном коде).
В зависимости от того, что делает старый код и определяемые вами интерфейсы, может иметь смысл использовать C ++ / CLI вместо C # для частей кода (он может работать с нативными указателями C ++ и управляемым кодом, что позволяет вам создавать простой переход при соединении между управляемым кодом .NET и собственным кодом C ++).
Заставьте новое приложение использовать модуль, выбранный в шаге 1.
Выберите новый модуль, вернитесь к шагу 2.
Преимущества:
будет выполнен рефакторинг (необходимо для разделения модулей)
в конце у вас должна быть батарея тестов для ваших функциональных модулей (если вы этого еще не сделали).
у вас все еще есть что-то, что можно отправить между ними.
Несколько заметок:
Если вы не используете распределенную разветвленную систему контроля версий, вам лучше работать с одним модулем за раз. Если вы используете управление ветвлением / распределенным исходным кодом, вы можете распределять разные модули по разным членам команды и централизовать изменения каждый раз, когда переносится что-то новое.
Очень важно, чтобы каждый шаг был четко разграничен (чтобы вы могли откатить свои изменения до последней стабильной версии, попробовать новые вещи и так далее). Это еще одна проблема, которая сложна с SVN и легко с Mercurial / Git.
Перед началом измените имена всех файлов вашего проекта на расширение .2005.vcproj и сделайте то же самое для файла решения. При создании нового файла проекта проделайте то же самое с .2010.vcxproj для файлов проекта и решения (вы все равно должны это сделать, если преобразуете решения / проекты). Идея состоит в том, что вы должны иметь параллельно и открывать, в зависимости от того, что вы хотите в любой точке. Вам не нужно обновлять дерево исходного кода для другой метки / тега / даты в элементе управления исходным кодом, просто чтобы переключать IDE.
Edit2: мы смотрели в письменной форме
COM-обернутые компоненты в C #, но
не имея опыта COM это страшно
и сложный.
Вы все еще можете сделать это, написав код-обертку (небольшой шаблонный класс интеллектуальных указателей для интерфейсов COM, например, не сработает - аналогично CComPtr в ATL). Если вы изолировали COM-код от некоторых оболочек, вы могли бы написать клиентский код (независимый от COM) без (почти) проблем.
Возможно ли создать C # dll
с прямым C-интерфейсом со всеми
управляемое благо скрыто внутри? Или же
COM - необходимое зло?
Не то, что я знаю. Я думаю, что COM будет неизбежным злом, если вы планируете использовать код сервера, написанный на C #, и код клиента на C ++.
Возможно наоборот.