Visual Studio 6中C++项目的推荐迁移策略

jac*_*see 10 c# c++ migration c++-cli visual-studio-6

对于使用Visual Studio 6用C++编写的大型应用程序,进入现代时代的最佳方式是什么?

我想采取渐进的方法,我们慢慢移动部分代码并将新功能编写到C#中,并将其编译成可以从遗留应用程序引用的库或DLL.

这是可能的,最好的方法是什么?

编辑:此时我们仅限于Express版本,我认为不允许使用我们当前应用程序中大量使用的MFC库.它也是一个相当大的应用程序,具有很多硬件依赖性,所以我不认为批量迁移是在卡片中.

Edit2:我们已经研究过在C#中编写COM包装的组件但是没有COM经验,这是可怕和复杂的.是否有可能生成一个带有直接C接口的C#dll,其中隐藏了所有托管优势?或者COM是必要的邪恶?

utn*_*tim 12

我想采取渐进的方法,我们慢慢移动部分代码

这是唯一可行的方法.

首先,你使用什么样的版本控制?(如果您使用分支版本控制,允许您进行实验并查看哪些有效,同时最大限度地降低了损害代码的风险;其他人也可以,但您必须非常小心,具体取决于您使用的内容).

编辑:我刚看到你正在使用SVN.如果你有权这样做,那么转向mercurial或git可能是值得的(这种改变为你能用代码库做些什么提供了一个巨大的飞跃).

然后将新功能编写到C#中,并将其编译成可以从遗留应用程序引用的库或DLL.

那......不一定是个好主意.C#代码可以公开可在C++中访问的COM接口.用C++编写用C#编写的模块的客户端代码可能很有趣,但你可能会觉得它很费力(就努力比例而言); 它也很慢且容易出错(与为C++编写的模块编写C#客户端代码相比).

最好考虑在C#中创建一个应用程序框架,并使用用C++编写的模块(用于核心功能).

这是可能的,最好的方法是什么?

是的,这是可能的.

有多少人参与了这个项目?

如果有很多,最好的方法是在新的应用程序框架上有一些(两个?四个?)工作,其余的就像往常一样继续.

如果很少,你可以考虑让一个人负责这个,或者更多的人从事兼职工作.

每个人(旧代码维护和新代码开发)分配的人员/工作的百分比应该取决于团队的规模和您的优先级(转换是否是低优先级问题?是否有必要在给定日期之前完成?)

执行此操作的最佳方法是开始调整代码模块以在多个场景中使用(使用旧代码和新代码)并继续并行开发(同样,通过使用分支分布可以大大简化这一点)版本控制系统).

以下是我将如何处理它(迭代开发,中间有小步骤和大量有效性检查):

  1. 在旧的代码库中选择一个功能模块(与GUI无关的东西).

  2. 从步骤1中选择的模块中删除MFC代码(以及VS2010 Express中不可用的其他库 - 如ATL)引用.

    不要尝试使用自定义代码重写MFC/ATL功能,除非进行小的更改(也就是说,决定创建自己的GUI框架是不可行的,但是可以决定编写自己的COM接口指针包装器,类似于ATL的CComPtr).

    如果代码严重依赖于库,则应尽可能将其分离,然后将其标记为使用新技术在未来的某个时刻重写.无论哪种方式,对于一个严重依赖于MFC的库,你最好用别的东西重写代码(C#?).

  3. 尽可能减少与所选模块的耦合(确保代码位于单独的库中,明确决定模块向客户端代码公开的功能)并仅通过决定的公开接口(在旧代码中)访问分隔功能.

  4. 确保旧的代码库仍然适用于已修改的模块(测试 - 最终自动化该模块的测试) - 如果您需要仍然留在市场上,直到您可以发布新版本,这是至关重要的.

  5. 在维护当前应用程序的同时,启动一个新项目(基于C#?),实现GUI和现代化所需的其他部分(如严重依赖于MFC的部分).这应该是一个薄层应用程序,最好是业务逻辑的不可知(应尽可能保留在遗留代码中).

    根据旧代码的作用和您定义的接口,对于部分代码使用C++/CLI而不是C#可能是有意义的(它可以与本机C++指针和托管代码一起使用,使您可以轻松转换管理.NET代码和C++本机代码之间的通信).

  6. 使新应用程序使用步骤1中选择的模块.

  7. 选择一个新模块,返回步骤2.

好处:

  • 将执行重构(模块分离所必需的)

  • 最后,您应该为您的功能模块进行一系列测试(如果您还没有).

  • 你还有东西可以在两者之间运送.

几点说明:

  • 如果您不使用分布式分支版本控制系统,那么最好一次只处理一个模块.如果使用分支/分布式源代码控制,则可以将不同的模块分发给不同的团队成员,并在每次移植新内容时集中更改.

  • 非常重要的是每个步骤都要明确分隔(这样您就可以将更改回滚到最后一个稳定版本,尝试新事物等等).这是SVN难以解决的另一个问题,使用Mercurial/Git很容易.

  • 在开始之前,将所有项目文件的名称更改为.2005.vcproj扩展名,并对解决方案文件执行相同操作.在创建新项目文件时,对.2010.vcxproj执行相同的项目文件和解决方案(如果转换解决方案/项目,仍应执行此操作).这个想法是你应该在任何一点上并行和打开你想要的任何一个.您不必为了切换IDE而对源代码管理中的其他标签/标记/日期进行源树更新.

Edit2:我们已经研究过在C#中编写COM包装的组件但是没有COM经验,这是可怕和复杂的.

您仍然可以通过编写包装器代码来实现它(例如,用于COM接口的小模板智能指针类不会出错 - 类似于ATL中的CComPtr).如果你在一些包装器后面隔离了COM代码,你可以编写客户端代码(与COM无关),几乎没有任何问题.

是否有可能生成一个带有直接C接口的C#dll,其中隐藏了所有托管优势?或者COM是必要的邪恶?

从来没听说过.如果您计划使用C#编写的服务器代码和C++中的客户端代码,我认为COM将是一个必要的恶魔.

反过来也是可能的.


mdm*_*dma 6

面对同样的任务,我的策略是这样的:

  1. 确定我们希望通过转向2010年的发展获得什么 - 它可能是

    • 提高质量保证:单元测试,模拟是现代开发工具的一部分
    • 更流畅的UI:WPF提供了现代的外观和感觉.
    • 生产力:在某些领域,.NET开发比C++开发更高效
    • 支持:新工具支持改进和错误修正.
  2. 确定系统的哪些部分不会从移动到C#中获得:

    • 硬件访问,低级算法代码
    • 几乎是大多数定制的非UI工作代码 - 如果它已经有效,就没有意义
  3. 确定需要将系统的哪些部分迁移到c#.对于这些部分,请确保C++中的当前实现是分离的和模块化的,以便可以交换这些部分.如果应用程序是一个整体,那么将需要大量的工作来重构应用程序,以便它可以被分解并选择在c#中重新实现的部分.(可以不重构任何内容,而只是专注于在c#中实现新的应用程序功能.)

  4. 既然你已经确定哪些部分将保留在C++中,哪些部分将用c#实现,(或者只是规定新功能在c#中),那么焦点转向如何将c#和c ++集成到一个解决方案中

    • 使用COM包装器 - 如果您现有的C++项目充分利用了OO,这通常不会像看起来那么困难.使用MSVC 6,您可以使用ATL类将类公开为COM组件.
    • 直接集成本机和c#代码.集成"遗留"编译代码需要一个中间DLL - 有关详细信息,请参阅此处.

混合使用MFC UI和c#UI可能无法实现,也无法建议,因为它会产生两种不同风格的UI组合(20世纪90年代灰色和2010年氛围).重点关注实现增量迁移,例如在c#中实现新的应用程序代码并从本机C++代码调用它.这样可以使迁移的c#代码数量保持较小.随着您对2010开发的更多了解,您可以采用无法逐步迁移的较大块(例如UI).