Was sind die Situationen oder Vor- und Nachteile von C ++ / CLI über C #?

8

Ich habe jetzt eine Weile mit .NET CLR Schritt gehalten, und meine Sprache der Wahl ist C #.

Bis vor kurzem war mir nicht bewusst, dass C ++ / CLI ausführbare Dateien im "gemischten Modus" erzeugen konnte, die nativen und verwalteten Code ausführen konnten.

Nachdem ich dies nun gewusst hatte, diskutierte ein anderer Entwicklerfreund von mir dieses Attribut und versuchte herauszufinden, wann und wie diese Fähigkeit nützlich wäre.

Ich gehe davon aus, dass nativer Code die -Fähigkeit besitzt, um effizienter und leistungsfähiger als managed Code zu sein, auf Kosten der zusätzlichen Entwicklungszeit.

In der Vergangenheit habe ich auf rein native C ++ - Code-Bibliotheken zurückgegriffen und Interop verwendet, um die Funktionalität zu nutzen, die ich in die native Bibliothek geschrieben habe.

Ich kann den Vorteil sehen, dass ich keine zusätzliche Bibliothek benötige, aber ich bin neugierig, was all die Vor- / Nachteile der Verwendung von C ++ / CLI über in C # erstellte, einfach zu verwaltende ausführbare Dateien oder eine solche ausführbare Datei mit Interop sind rein native C ++ - Bibliothek?

(Hinweis: Sind die Begriffe Interop / PInvoke austauschbar, da ich den Unterschied zwischen den Begriffen nicht verstehe, einfach so, wie sie verwendet werden.)

    
Brett Allen 09.12.2009, 15:47
quelle

4 Antworten

13

Mit C ++ / CLI können Sie grob gesagt drei Arten von Objekten erstellen:

  1. Verwaltete Typen Diese werden auf im Wesentlichen die gleiche IL wie das äquivalente C # kompiliert. Hier gibt es keine Leistungsmöglichkeiten.
  2. Native Typen Kompiliert den systemeigenen Code, als ob Sie direkt C ++ verwendet hätten.
  3. Gemischte Modustypen Diese kompilieren sich zu verwaltetem Code, erlauben Ihnen aber auch, auf native Typen zu verweisen.

Man könnte sich (3) so vorstellen, als würde man C # -Code mit PInvoke-Code schreiben, um auf das native Zeug zuzugreifen - außer dass das PInvoke-Zeug für dich erzeugt wird.

Es gibt natürlich mehr als das, genauso wie einige Vorbehalte - aber das sollte Ihnen eine Vorstellung davon geben, wie es nützlich ist.

Mit anderen Worten, es ist wirklich eine Leimsprache. Während Sie voll entwickelte Anwendungen in C ++ / CLI schreiben können, ist es normaler, die verwalteten und nativen Teile getrennt zu halten und C ++ / CLI zu verwenden, um die beiden sauberer als mit PInvoke zu überbrücken.

Eine weitere häufige Verwendung ist die Erweiterung und vorhandene native C ++ - Codebasis mit .Net-Bibliotheksaufrufen.

Seien Sie nur vorsichtig, dass Sie Ihren Code gut partitionieren, da er manchmal sehr subtil sein kann, wenn Sie Ihren reinen C ++ - Code transparent in IL kompilieren!

Zu Ihrer Anmerkung: PInvoke ist eine bestimmte Art von Interop. Interop kommt auch in anderen Formen, wie COM Interop. Genau genommen ist PInvoke eine Reihe von Sprachfunktionen, die Interop mit nativem Code einfacher machen.

    
philsquared 09.12.2009, 15:56
quelle
3

Ich habe Managed C ++ (die Vorgängerversion von .NET 1.1 zu C ++ / CLI) in der Vergangenheit effektiv verwendet. Ich finde es am besten funktioniert, wenn Sie eine native C oder C ++ - Bibliothek haben, die Sie in verwaltetem Code verwenden möchten. Sie könnten die gesamte Interop / PInvoke-Route gehen, die für einige hässliche C # -Code und häufig Marshalling-Probleme, oder Sie könnten einen verwalteten C ++ - Wrapper schreiben, wo C ++ / CLI wirklich glänzt.

Da es sich bei C ++ / CLI um verwalteten Code handelt, können Sie ihn von C # (oder VB.NET, wenn Sie auf diese Weise lehnen) auf normale Weise aufrufen, indem Sie einen Verweis auf die .DLL-Datei hinzufügen. Kein Rangieren, kein Import, nichts so doof. Nur normale Projektreferenzen. Zusätzlich erhalten Sie den Vorteil von statisch verknüpften Bibliotheken, wenn Ihre native Bibliothek so konzipiert ist, was ein Good Thing (tm) ist.

    
Randolpho 09.12.2009 15:58
quelle
2

Phil Nash traf wirklich die großen Dinge. Hier ist eine mehr, die ich mehr als einmal getroffen habe und der Hauptgrund ist, warum ich C ++ / CLI in der Vergangenheit benutzt habe:

Einige Anwendungen werden erweitert, indem alle DLLs an einem Speicherort auf exportierte Funktionen mit einem bestimmten Namen überprüft werden. In C # gibt es keine Möglichkeit, einen nativen C-Style-Export zu deklarieren, aber Sie können in C ++ / CLI. Ich erstelle einen "Wrapper" in C ++ / CLI, der die Methode exportiert, jede Übersetzung von C-Strukturen in verwaltete Objekte behandelt und den Aufruf an eine in C # geschriebene Assembly weitergibt.

    
Sam Harwell 09.12.2009 16:04
quelle
1

Es gibt bestimmte Typen, die für andere Sprachen nicht verfügbar sind Const und Tracking-Handle von Boxed-Value-Typen.

Templates sind auf die Kompilierzeit spezialisiert. Generika sind zur Laufzeit spezialisiert. Obwohl CLR die Generics-Spezialisierung für die zukünftige Verwendung zwischenspeichern sollte (damit Sie bei jeder Verwendung die gleiche Liste erhalten), wird jedes Mal, wenn eine Generika-Spezialisierung angefordert wird, ein Leistungseinbruch verzeichnet.

Ich weiß, dass andere Sprachen das const-Attribut verwerfen, aber die Überprüfung der Kompilierzeit in Ihrem C ++ - Code ist besser als nichts.

Wenn Sie einen Typ wie int ^ verwenden, können Sie auf den Speicher im verwalteten Heap-Verzeichnis zugreifen, ohne unnötiges Unboxing durchzuführen. Dies kann die Leistung verbessern, wenn Tracking-Handles von Box-Werten an Funktionen übergeben werden, die ein Tracking-Handle erwarten, z. B. Console :: WriteLine (Object ^). Natürlich kann die frühe Box-Initialisierung nicht vermieden werden. In anderen Sprachen können Sie den Verweis in einer Object-Variablen speichern und übergeben, um das Unboxing zu vermeiden, aber Sie verlieren die Überprüfung des Kompilierzeittyps.

    
Sheng Jiang 蒋晟 09.12.2009 21:21
quelle

Tags und Links