我目前正处于需要在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#链接
哪一个是最好的方法?或者,如果有更好的解决方案,它是什么?
答案 0 :(得分:3)
C ++ / CLI对标准C ++有一些限制,并不总是能够轻松地将标准C ++重新编译为C ++ / CLI。请记住,对于初学者,您必须区分“托管”和“非托管”指针。由于这些是使用不同的符号,你已经有了第一组#ifdefs。然后你就可以参考并重视课程和所有这些乐趣。
但是,您可以使用C ++ / CLI来弥合本机代码和.NET世界之间的差距。我最后一次按照你计划做的事情做了一些事情,我使用C ++ / CLI编写桥接层,在.NET类型和类与本机世界之间进行必要的转换和转换工作。显然,C ++ / CLI层可以在任何.NET语言中使用。
您不能总是使用(2) - 这在很大程度上取决于您尝试在两个世界之间交换的数据类型。 .NET编组代码非常擅长处理C POD,但更复杂,你遇到了问题。
(3)过度使用恕我直言并引入另一个失败点,再加上你正在做.NET< - > COM< - >本机而不是更简单的.NET< - >如果您创建了自己的桥接代码,则为native。更不用说你在你的代码中添加了一个复杂功能,它不会使你所针对的其他操作系统受益,即OS X.
答案 1 :(得分:2)
我们的开发团队一直在使用带有ASP.NET和WPF前端的C ++ / CLI编译代码。
我们遇到的第一个主要问题是构建时间。代码库将是150k行(40多个项目)并且永远链接(由于链接器问题,我们无法将各个项目构建为DLL)。我们只能通过使用托管C ++类包装代码并将项目构建为程序集来解决此问题。
第二个主要问题是表现。我们最初用/ clr编译(在纯选项存在之前),这导致我们在托管C ++层中发生的大多数调用的双重thunking。我们通过切换到/ clr:pure来修复此问题。通过这样做,我们遇到了一个 我们的程序集导致程序集中有太多“全局”方法导致它们无法加载的问题。我们不得不进一步拆分我们的组件以解决这个问题。
答案 2 :(得分:1)
最好也更简单的方法是使用.NET< - > COM因为与.NET中的本机dll访问相比,COM具有更强大的桥接,因为它可能导致大量内存问题和大量的故障排除时间。它更容易在任何MFC项目中测试COM并获得用于调试的跟踪信息,当组件准备好时,它可以在.NET内轻松使用。
CLI不会让你使用所有功能,不幸的是它相当新,所以文档较少,你不会得到很好的支持。
Win32 dll和DLLImport主要有问题排除故障,因为Win32 dll内部抛出的异常不会沿着堆栈进一步传播,而是简单地崩溃,你不会理解。在COM中的其他位置,您可以在内部捕获异常,并且在.NET中抛出的COMException不会使整个应用程序崩溃。
COM在性能上会稍微慢一些,但它会更有条理,更好的设计模式可以开发。