2009-12-09 17 views
8

Sono stato al corrente di .NET CLR per un po 'di tempo e la mia lingua preferita è C#.Quali sono le situazioni o i pro e i contro dell'uso di C++/CLI su C#

Fino a poco tempo fa, non ero a conoscenza del fatto che C++/CLI potesse produrre eseguibili "in modalità mista" in grado di eseguire codice nativo e gestito.

Ora sapendo questo, un altro mio amico sviluppatore stava discutendo di questo attributo e stava cercando di determinare quando e come questa abilità sarebbe stata utile.

Prendo come dato che il codice nativo ha la capacità per essere più efficiente e potente del codice gestito, a scapito del tempo di sviluppo aggiuntivo.

In passato, ho fatto ricorso a librerie di codici C++ strettamente nativi e ho utilizzato Interoper per utilizzare la funzionalità che ho scritto nella libreria nativa.

Vedo il vantaggio di non richiedere una libreria aggiuntiva, ma sono curioso di sapere quali sono tutti i pro/contro dell'uso di C++/CLI su un solo eseguibile gestito in C#, o un tale eseguibile che utilizza Interop per chiamare una libreria C++ puramente nativa?

(Nota a margine:. Sono i termini di interoperabilità/PInvoke intercambiabili, come ho d.on't capire la differenza tra i termini, semplicemente visti usati allo stesso modo)

risposta

13

con C++/CLI è possibile creare, in generale, tre tipi di oggetti:

  1. tipi gestiti. Questi si compileranno essenzialmente per lo stesso IL dell'equivalente C#. Non ci sono opportunità di spettacolo qui.
  2. Tipi nativi. Compila il codice nativo come se avessi usato il C++.
  3. Tipi di modalità mista. Questi si compileranno sul codice gestito, ma ti permetteranno di fare riferimento anche ai tipi nativi.

Si potrebbe pensare di (3) ad essere come la scrittura di codice C# con il codice di PInvoke per l'accesso alla roba nativa - tranne che tutta la roba PInvoke viene generato per voi.

C'è di più, ovviamente, oltre ad alcuni avvertimenti, ma questo dovrebbe darvi un'idea di come sia utile.

In altre parole, è davvero un linguaggio di colla. Mentre è possibile scrivere applicazioni complete in C++/CLI, è più normale mantenere separate le parti gestite e native e utilizzare C++/CLI per collegare le due parti in modo più pulito rispetto a PInvoke.

Un altro uso comune è l'estensione e la codifica di codice C++ esistente, nativa con le chiamate di libreria .Net.

Basta fare attenzione a suddividere il codice in modo corretto, in quanto talvolta può essere piuttosto complicato compilare il proprio codice C++ in IL in modo trasparente!

Per quanto riguarda il vostro sidenote: PInvoke è un particolare tipo di Interop. Interop è disponibile anche in altre forme, come COM Interop. Infatti, più precisamente, PInvoke è un insieme di funzionalità linguistiche che semplificano l'interoperabilità con il codice nativo.

+2

+1 per chiamarlo linguaggio di colla. Migliore descrizione di C++/CLI ancora. – Randolpho

+0

sì, e i fumi possono essere ugualmente tossici ;-) – philsquared

+0

Oh, non lo so. Mi piace piuttosto, in realtà. – Randolpho

3

Ho usato Managed C++ (il precursore .NET 1.1 in C++/CLI) in modo efficace in passato. Trovo che funzioni meglio quando hai una libreria nativa C o C++ che desideri utilizzare nel codice gestito.Potresti andare all'intero percorso Interop/PInvoke, che genera un brutto codice C# e spesso ha problemi di marshalling, oppure potresti scrivere un wrapper C++ gestito, che è dove C++/CLI brilla davvero.

Poiché C++/CLI è il codice gestito, è possibile chiamarlo da C# (o VB.NET se si inclina in quel modo) nel modo normale, aggiungendo un riferimento a .DLL. Niente marshalling, niente dllimport, niente sciocchezze come quello. Solo normali riferimenti al progetto. Inoltre, si ottiene il beneficio delle librerie statiche collegate se la propria libreria nativa è progettata in tal modo, che è una buona cosa (tm).

2

Phil Nash ha colpito davvero le grandi cose. Eccone un'altra che ho colpito più di una volta ed è la ragione principale per cui ho usato C++/CLI in passato:

Alcune applicazioni sono estese controllando tutte le DLL in qualche posizione per le funzioni esportate con un nome particolare. In C#, non c'è modo di dichiarare un'esportazione nativa in stile C, ma è possibile in C++/CLI. Creo un "wrapper" in C++/CLI che esporta il metodo, gestisce qualsiasi traduzione di strutture C in oggetti gestiti e passa la chiamata a un assembly scritto in C#.

+0

Questa è un'idea molto interessante, non ci ho mai pensato. –

1

Ci sono alcuni tipi che non sono disponibili in altre lingue, come i modelli, const e l'handle di monitoraggio dei tipi di valore in box.

i modelli sono specializzati in fase di compilazione. i generici sono specializzati in runtime. Anche se CLR dovrebbe memorizzare nella cache la specializzazione dei generici per un uso futuro (in modo da ottenere lo stesso elenco ogni volta che lo si utilizza), c'è sempre un problema di prestazioni ogni volta che viene richiesta una specializzazione generica.

so che altre lingue scartano l'attributo const, ma il controllo del tempo di compilazione nel codice C++ è meglio di niente.

Avere un tipo come int^consente di accedere alla memoria nella directory heap gestita senza unboxing non necessario. Questo può aiutare le prestazioni quando si passano le maniglie di rilevamento dei valori in box alle funzioni che prevedono un handle di monitoraggio, come Console :: WriteLine (Object ^). Naturalmente l'iniziale inizializzazione della boxe non può essere evitata. In altre lingue è possibile memorizzare il riferimento in una variabile Object e passarlo per evitare l'unboxing, ma si perde il controllo del tipo di tempo di compilazione.

+0

I generici non sono modelli. La prima volta che accederai a una versione tipizzata di riferimento del generico, si verificherà un impatto sulle prestazioni. Una volta fatto, riutilizzerà lo stesso tipo di riferimento generico per tutti i tipi che non invocheranno il compilatore. Chiaramente se si dispone di un tipo precompilato per un dato oggetto tramite modelli, allora sarà più veloce. – Spence

+1

Il riutilizzo viene eseguito controllando la cache di tipo generico. Il controllo non è gratuito. –

+0

I generici non sono affatto specializzati. –

Problemi correlati