繁体   English   中英

如何在WPF C#GUI中使用跨平台C ++

[英]How to use cross platform C++ with a WPF C# GUI

我目前在一个需要同时在Mac和Windows上运行的项目中。 我们正在为所有应用程序逻辑使用标准的可移植C ++。 但是,由于我们希望该应用程序在这两个平台上都感觉完全原生,因此该GUI将使用Windows的C#/ WPF和Mac的Objective-C / Cocoa编写。

但是,对于Windows部分,我想知道在C#中使用C ++代码的最佳方法是什么。 C#是托管的,而且我知道我们也可以使用托管C ++。 但是,我担心在CLR中使用C ++可能会引入意外的错误,否则我们将需要在C ++代码中的每处都放置大量的#ifdef WIN32,以使其与托管CLR和Mac OS X的非托管环境一起工作。 (请注意,我们当然希望添加一些 ifdef,但如果可能的话,我们希望对其进行控制)。 因此,基本上,将C ++代码与C#代码一起使用的最佳方法是什么? 现在,我正在考虑三种解决方案

1-将C ++编译为C ++ / CLI,并直接使用C#中的类和函数。

2-将C ++编译并包装在非托管的Win32 dll中,并使用DllImport从C#调用它

3-将C ++包装在COM包装器中,并使用.NET COM Interop将其与C#链接

哪一种是最好的方法? 或者,如果有更好的解决方案,那是什么?

C ++ / CLI对标准C ++有一些限制,这些限制并不总是使将C ++ / CLI重新编译为C ++容易。 请记住,对于初学者,您必须区分“托管”和“非托管”指针。 由于这些使用不同的符号,因此您已经有了第一组#ifdef。 然后,您将获得ref和value类,以及所有的乐趣。

但是,您可以使用C ++ / CLI来弥合本机代码和.NET世界之间的鸿沟。 上一次我按照您的计划进行操作时,我使用C ++ / CLI编写了桥接层,该层在.NET类型和类与本机世界之间进行了必要的转换和转换工作。 显然,可以从任何.NET语言中使用C ++ / CLI层。

您不能总是使用(2)-这在很大程度上取决于您要在两个世界之间交换的数据类型。 .NET编组代码非常适合处理C POD,但是任何更复杂的事情都会给您带来麻烦。

(3)是IMHO的过大杀伤力,并引入了另一个故障点,另外,如果您创建了自己的桥接代码,则您将执行.NET <-> COM <->本机,而不是更简单的.NET <->本机。 更不用说您在代码中添加了复杂性,而这不会使您要定位的其他OS(即OS X)受益。

我们的开发团队已经将C ++ / CLI编译的代码与ASP.NET和WPF前端一起使用了一段时间。

我们遇到的第一个主要问题是构建时间。 代码库将是15万行(40多个项目),并且花了很多时间进行链接(由于链接器问题,我们无法将单个项目构建为DLL)。 我们只能通过使用托管C ++类包装代码并将项目构建为程序集来解决此问题。

第二个主要问题是性能。 我们最初使用/ clr进行编译(在存在纯选项之前),这导致在托管C ++层中发生的大多数调用都发生了两次重击。 我们通过切换到/ clr:pure来解决此问题。 这样做会遇到一个问题,即程序集导致程序集中有太多“全局”方法,因此它们无法加载。 为了解决这个问题,我们不得不进一步拆分程序集。

最好和更简便的方法是使用.NET <-> COM进行此操作,因为与.NET内部的本机dll访问相比,COM具有更强大的桥接,因为它可能导致大量内存问题和大量故障排除时间。 它更容易在任何MFC项目中测试COM并获取跟踪信息以进行调试,并且当组件准备就绪时,可以在.NET内部轻松使用它。

CLI不会让您使用所有功能,但不幸的是,它的功能很新,因此可用的文档更少,您对问题的支持也不会很好。

Win32 dll和DLLImport主要存在问题来进行故障排除,因为Win32 dll中引发的异常不会沿着堆栈进一步传播,而是只会崩溃,而您将无法得到原因。 在COM的其他地方,您可以在内部捕获异常,而.NET中引发的COMException不会使整个应用程序崩溃。

COM的性能将稍慢一些,但是它将更加有条理,并且可以开发出良好的设计模式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM