6

我的整个应用程序(相当大,有 20MB 的可执行文件)是用非托管 C++ 编写的。因为我可以清楚地看到使用托管代码的优势,所以我想开始在我的应用程序中引入托管代码,但是从哪里开始呢?

我可以轻松开始使用 C++/CLI 并将其与我的应用程序的其余部分链接吗?(尽管 C++/CLI 语法看起来相当“异国情调”)。

还是迁移到 C# 更好,但是将它与我​​的非托管 C++ 代码“链接”在一起的最佳方法是什么?

使用 /clr 选项编译我的所有 C++ 代码是否有意义?这行得通吗?

我需要担心编组吗?这是否会产生开销,或者我可以在托管和非托管之间切换而不会降低性能(就像我 20 年前混合 fortran 和 C 时所做的那样)。性能在我的应用程序中非常重要,因为它是一个有时会处理数 GB 内存的科学应用程序。

还是只重新设计用户界面才有意义,只用 C# 编写它,并将我的应用程序的其余部分(计算逻辑、业务逻辑、数据库接口……)保留在非托管 C++ 中?

由于我的应用程序有时需要处理几千兆字节的内存,所以我有一个 64 位的变体。拥有 64 位托管代码容易吗?如果使用那么多内存,垃圾收集器是否仍然有效?

简单地说:我从哪里开始?

帕特里克

4

3 回答 3

1

我们完全按照您在数千名用户使用的关键任务应用程序中描述的方式进行操作。基本上,我们保持现有应用程序不变,因此可执行文件仍然是 100% 非托管可执行文件(不是 C++/CLI)。然后,我们将所有新的 C# 代码放入 .NET dll 中,其中包括业务对象、用户控件和 gui 代码等......

基本上,所有新代码都是用 C# 编写的。我们有 1 个 dll,它是 C++/CLI,只是胶水。这让我们可以轻松地在托管代码和非托管代码之间进行互操作,而无需将现有的 C++ 代码设置为 clr。这限制了我们必须编写的 C++/CLI 代码的数量。本机代码与混合模式代码对话,混合模式代码可以与托管代码对话。混合模式 dll 可以挂钩 C# 类上的事件,因此 C# 代码可以触发事件以与 C++/CLI 通信(可以与本机代码通信)。

我们还可以在现有的 C++ 应用程序中托管 .NET UserControls(无论如何,WinForms 只是 WINAPI 的一个包装器,所以它工作得很好)。

这非常有效,并且可以让您保留现有代码,而无需用 C# 重写整个 GUI。

于 2009-12-18T03:12:35.787 回答
1

分析应用程序,决定在哪些集成点可以断开 C# 逻辑线并进入 C++,反之亦然。将这些安排成一个计划,以使 Facade 设计模式在系统中移动,逐渐用 C# 代替 C++。在决定在每个候选外观/界面上切换语言时,关键问题是 CPU 和内存成本。

您将希望能够合并编辑,因此您可能最好使用原始 C++ 代码的一个源代码集和源代码存储库以及外观和 C# 的另一个集和存储库。

然后,当增强/维护工作进入托盘时,您将其应用于两个代码库,并尝试确保外观在系统中移动,从增强或维护中最不可能更改的代码开始,以最大限度地减少更改工作的加倍.

还可以理想地组织您的工作,以便您可以在遇到障碍时立即回滚外观以返回 100% C++。

要测试几个特别难以理解的 C++ 模块是否可以分成 C++ 部分和 C# 部分,请在使用管道或套接字进行通信的两个不同 Win32 C++ 进程中运行它们。这样,您将更好地了解内存管理或性能是否存在需要修复的问题,然后才能拆分调用链。

于 2009-12-17T17:30:57.937 回答
1

目前,认为这个问题已经结束。

我意识到答案不是混合 C++ 和 C#,而是首先让架构正确。

如果架构是正确的,并且在需要分开的地方分开,那么通过其他模块(外部,其他语言,......)更改应用程序的部分应该更容易。

关于编组过程中的性能问题,我们将不得不等到 .Net 进一步成熟。

于 2010-02-10T13:22:42.200 回答