コードの一部をゆっくりと移動するインクリメンタルアプローチを採用したいと思います
それがそれを行う唯一の現実的な方法です。
まず、どのようなバージョン管理を使用していますか?(コードを危険にさらすリスクを最小限に抑えながら、実験を行って何が機能するかを確認できる分岐バージョン管理を使用する場合。他のバージョンも問題ありませんが、使用するものによっては十分に注意する必要があります)。
編集:あなたがSVNを使用しているのを見ました。それを行う自由がある場合は、mercurialまたはgitに移行する価値があるかもしれません(この変更により、コードベースで実行できることは飛躍的に向上します)。
たとえば、新しい機能をC#に書き込み、それをレガシーアプリケーションから参照できるライブラリまたはdllにコンパイルします。
それは...必ずしも良い考えではありません。C#コードは、C++でアクセス可能なCOMインターフェイスを公開できます。C#で記述されたモジュール用にC ++でクライアントコードを記述することは楽しいことですが、(利益に対する努力の比率の点で)負担がかかる場合があります。また、速度が遅く、エラーが発生しやすくなります(C ++で記述されたモジュールのC#クライアントコードを記述する場合と比較して)。
C#でアプリケーションフレームワークを作成し、コア機能にC ++で記述されたモジュール(すでに)を使用することを検討することをお勧めします。
これは可能ですか、それを行うための最良の方法は何ですか?
はい、可能です。
プロジェクトには何人の人が関わっていますか?
多くの場合、最良の方法は、新しいアプリケーションフレームワークでいくつか(2?4?)作業を行い、残りを通常どおり続行することです。
人数が少ない場合は、担当者かアルバイトをすることを検討してください。
それぞれ(古いコードの保守と新しいコードの開発)に割り当てられる人/労力の割合は、チームの規模と優先順位によって異なります(移行は優先度の低い問題ですか?特定の日付までに完了する必要がありますか?)
これを行うための最良の方法は、コードのモジュールを複数のシナリオで使用できるように(古いコードと新しいコードの両方で)適応させ始め、並行して開発を継続することです(これも、分散型の分岐を使用することで大幅に容易になりますバージョン管理システム)。
これが私がそれをどのように進めるかです(小さなステップと多くの妥当性チェックを間に挟んだ反復型開発):
古いコードベースで機能モジュール(GUIに関連しないもの)を選択します。
手順1で選択したモジュールから、MFCコード(およびVS2010 Expressで使用できない他のライブラリ-ATLなど)の参照を削除します。
小さな変更がない限り、MFC / ATL機能をカスタムコードで書き直そうとしないでください(つまり、独自のGUIフレームワークを作成することはできませんが、次のような独自のCOMインターフェイスポインターラッパーを作成することはできます。 ATLのCComPtr)。
コードがライブラリに大きく依存している場合は、可能な限り分離してから、新しいテクノロジーを使用して将来書き直すためにマークを付けてください。いずれにせよ、MFCに大きく依存しているライブラリの場合は、他の何か(C#?)を使用してコードを書き直す方がよいでしょう。
選択したモジュールとの結合を可能な限り減らし(コードが別のライブラリにあることを確認し、モジュールがクライアントコードに公開する機能を明確に決定します)、決定された公開インターフェイス(古いコード)を介してのみ区切られた機能にアクセスします。
古いコードベースが変更されたモジュールで引き続き機能することを確認します(テスト-最終的にこのモジュールのテストを自動化します)-新しいバージョンを出荷するまで市場にとどまる必要がある場合、これは重要です。
現在のアプリケーションを維持しながら、GUIおよび最新化する必要のあるその他の部分(MFCに大きく依存する部分など)を実装する新しいプロジェクト(C#ベース?)を開始します。これはシンレイヤーアプリケーションである必要があり、できればビジネスロジックに依存しないようにする必要があります(可能な限りレガシーコードに残す必要があります)。
古いコードの機能と定義するインターフェイスによっては、コードの一部にC#ではなくC ++ / CLIを使用するのが理にかなっている場合があります(ネイティブC ++ポインターとマネージコードで機能するため、次の場合に簡単に移行できます。マネージ.NETコードとC++ネイティブコード間の通信)。
手順1で選択したモジュールを新しいアプリケーションで使用するようにします。
新しいモジュールを選択し、手順2に戻ります。
利点:
いくつかの注意:
分散分岐バージョン管理システムを使用しない場合は、一度に1つのモジュールで作業することをお勧めします。分岐/分散ソース管理を使用する場合は、さまざまなモジュールをさまざまなチームメンバーに配布し、新しいものが移植されるたびに変更を一元化できます。
各ステップが明確に区切られていることが非常に重要です(変更を最後の安定バージョンにロールバックしたり、新しいことを試したりできるようにするため)。これは、SVNでは難しく、Mercurial/Gitでは簡単なもう1つの問題です。
開始する前に、すべてのプロジェクトファイルの名前を.2005.vcproj拡張子に変更し、ソリューションファイルに対しても同じことを行います。新しいプロジェクトファイルを作成するときは、プロジェクトファイルとソリューションに対して.2010.vcxprojを使用して同じことを行います(ソリューション/プロジェクトを変換する場合は、これを行う必要があります)。アイデアは、いつでも好きな方を並行して開いておく必要があるということです。IDEを切り替えるためだけに、ソース管理で別のラベル/タグ/日付にソースツリーを更新する必要はありません。
Edit2:COMでラップされたコンポーネントをC#で作成することを検討しましたが、COMの経験がないため、これは恐ろしく複雑です。
ラッパーコードを作成することで、それを行うことができます(たとえば、COMインターフェイス用の小さなテンプレート化されたスマートポインタークラスは、ATLのCComPtrと同様に失敗しません)。一部のラッパーの背後にあるCOMコードを分離した場合、(COMに関係なく)クライアントコードを(ほとんど)問題なく記述できます。
すべての管理された良さを内部に隠したストレートCインターフェイスでC#dllを生成することは可能ですか?それともCOMは必要悪ですか?
私が知っていることではありません。C#で書かれたサーバーコードとC ++で書かれたクライアントコードを使うつもりなら、COMは必要悪だと思います。
逆の可能性もあります。