如何在 WPF C# GUI 中使用跨平台 C++
Posted
技术标签:
【中文标题】如何在 WPF C# GUI 中使用跨平台 C++【英文标题】:How to use cross platform C++ with a WPF C# GUI 【发布时间】:2009-09-24 05:48:43 【问题描述】:我目前的项目需要同时在 Mac 和 Windows 上运行。我们为所有应用程序逻辑使用标准的可移植 C++。但是,由于我们希望应用程序在这两个平台上都感觉完全原生,所以 GUI 将使用 C#/WPF for Windows 和 Objective-C/Cocoa for Mac 编写。
但是,对于 Windows 部分,我想知道将 C++ 代码与 C# 一起使用的最佳方法是什么。 C# 是托管的,我知道我们也可以使用托管 C++。但是我担心在 CLR 中使用 C++ 可能会引入意想不到的错误,或者我们需要在 C++ 代码中到处放置大量#ifdef WIN32 以使其与托管 CLR 和 Mac OS X 的非托管环境一起工作(请注意,我们确实希望放置 一些 ifdef,但我们希望尽可能控制它)。所以基本上,将 C++ 代码与 C# 代码一起使用的最佳方式是什么?目前,我正在考虑三种解决方案
1-将C++编译为C++/CLI,直接使用C#中的类和函数。
2- 在非托管 win32 dll 中编译和包装 C++,并使用 DllImport 从 C# 调用它
3- 将 C++ 包装在 COM 包装器中,并使用 .NET COM Interop 将其与 C# 链接
哪一个是最好的方法?或者,如果有更好的解决方案,它是什么?
【问题讨论】:
(WPF 在 Windows 上完全是原生的?)你可以使用 Qt 在两个平台上获得体面的原生外观(虽然在 Mac 上比 Windows 更糟糕)和完全可移植的 UI 代码。 是的,我们非常重视在项目中使用 Qt,但我们确实需要对 MAC OS X 有一种非常原生的感觉,所以我们决定使用每个操作系统的原生库。跨度> 【参考方案1】:C++/CLI 对标准 C++ 有一些限制,这些限制并不总是使将标准 C++ 重新编译为 C++/CLI 变得容易。请记住,对于初学者,您必须区分“托管”和“非托管”指针。由于它们使用不同的符号,因此您已经获得了第一组#ifdefs。然后你会得到 ref 和 value 类以及所有这些乐趣。
但是,您可以使用 C++/CLI 来弥合本机代码和 .NET 世界之间的差距。上次我按照您的计划做某事时,我使用 C++/CLI 编写了桥接层,该层在 .NET 类型和类与本机世界之间进行必要的翻译和转换工作。 C++/CLI 层显然可以在任何 .NET 语言中使用。
您不能总是使用 (2) - 这在很大程度上取决于您尝试在两个世界之间交换的数据类型。 .NET 编组代码在处理 C POD 方面非常出色,但任何更复杂的东西都会出现问题。
(3) 恕我直言,这太过分了,并且引入了另一个故障点,而且如果您创建了自己的桥接代码,那么您将使用 .NET COM native 而不是更简单的 .NET native。更不用说您在代码中添加了对您所针对的其他操作系统(即 OS X)无益的复杂性。
【讨论】:
【参考方案2】:我们的开发团队一直在使用 C++/CLI 编译代码和 ASP.NET 和 WPF 前端。
我们遇到的第一个主要问题是构建时间。代码库将是 150k 行(40 多个项目)并且需要永远链接(由于链接器问题,我们无法将单个项目构建为 DLL)。我们只能通过使用托管 C++ 类包装代码并将我们的项目构建为程序集来解决此问题。
第二个主要问题是性能。我们最初是用 /clr 编译的(在 pure 选项存在之前),这导致了我们在托管 C++ 层中发生的大多数调用的双重重复。我们通过切换到 /clr:pure 解决了这个问题。通过这样做,我们遇到了一个 我们的程序集导致程序集中的“全局”方法过多,因此无法加载的问题。我们不得不进一步拆分我们的程序集来解决这个问题。
【讨论】:
【参考方案3】:最好和更简单的方法是使用 .NET COM,因为与 .NET 中的本地 dll 访问相比,COM 具有更强大的桥接,因为它可能会导致大量内存问题和大量故障排除时间。它更容易在任何 MFC 项目中测试 COM 并获取用于调试的跟踪信息,并且当组件准备好时,它可以在 .NET 中轻松使用。
CLI 不会让您使用所有功能,不幸的是它相当新,因此可用的文档较少,您的问题也不会得到很好的支持。
Win32 dll 和 DLLImport 的问题主要是为了解决问题,因为在 Win32 dll 中抛出的异常不会沿着堆栈进一步传播,而是会简单地崩溃,你不会得到原因。在 COM 的其他地方,您可以在内部捕获异常,并且在 .NET 中抛出的 COMException 不会使您的整个应用程序崩溃。
COM 的性能会稍慢一些,但它会更有条理,并且可以开发出良好的设计模式。
【讨论】:
以上是关于如何在 WPF C# GUI 中使用跨平台 C++的主要内容,如果未能解决你的问题,请参考以下文章