簡體   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