Codice pure e verificabile (C++/CLI)
Nell'ambito della programmazione .NET, Visual C++ supporta la creazione di tre diversi tipi di applicazioni e componenti: misti, pure e verificabili.Tutti e tre i tipi sono disponibili con l'opzione del compilatore /clr (Compilazione Common Language Runtime).
Note
Per ulteriori informazioni sugli assembly verificabili, vedere:
Confronto tra le modalità mista, pura e verificabile (C++/CLI)
Conversione di progetti da modalità mista a linguaggio intermedio (IL) puro
Misto (/clr)
Gli assembly misti (compilati con /clr) contengono parti sia gestite che non gestite, in modo da poter utilizzare le funzionalità .NET. Tuttavia, contengono ancora codice non gestito.Questo consente di aggiornare applicazioni e componenti per l'utilizzo delle funzionalità .NET senza dover riscrivere l'intero progetto.L'utilizzo di Visual C++ per combinare codice gestito e non gestito nel modo descritto viene definito interoperabilità C++.Per ulteriori informazioni, vedere Assembly misti (nativi e gestiti) e Interoperabilità .NET e nativa.
Pure (/clr:pure)
Gli assembly pure (compilati con /clr:pure) possono contenere tipi di dati sia nativi che gestiti, ma solo funzioni gestite.Analogamente agli assembly misti, gli assembly pure consentono l'interoperabilità con DLL native tramite P/Invoke (vedere Utilizzo esplicito di PInvoke in C++ (attributo DllImport)), ma le funzionalità di interoperabilità C++ non sono disponibili.Questi tipi di assembly non sono inoltre in grado di esportare funzioni richiamabili da funzioni native, poiché i punti di ingresso di un assembly pure utilizzano la convenzione di chiamata __clrcall.
Vantaggi offerti da /clr:pure
Migliori prestazioni: poiché gli assembly pure contengono solo codice MSIL e di conseguenza non sono presenti funzioni native, le transizioni gestite/non gestite non sono necessarie(le chiamate di funzione effettuate tramite P/Invoke rappresentano un'eccezione a questa regola).
Compatibilità con AppDomain: le funzioni gestite e i tipi di dati CLR sono presenti all'interno di Application Domains e questo influisce sulla relativa visibilità e accessibilità.Poiché gli assembly pure tengono conto dei domini (__declspec(appdomain) è implicito in ogni tipo), l'accesso ai relativi tipi e funzionalità da altri componenti .NET risulta più semplice e sicuro.Di conseguenza, gli assembly pure interagiscono con altri componenti .NET più facilmente rispetto agli assembly misti.
Caricamento non su disco: gli assembly pure possono essere caricati in memoria o trasmessi.Questa caratteristica è essenziale per poter utilizzare gli assembly .NET come stored procedure.Per poter essere eseguiti, gli assembly misti devono invece essere memorizzati su disco, a causa di una dipendenza dai meccanismi di caricamento di Windows.
Reflection: non è possibile effettuare la reflection di eseguibili misti, mentre gli assembly pure forniscono il supporto completo della reflection.Per ulteriori informazioni, vedere Reflection (C++/CLI).
Controllabilità dell'host: poiché contengono solo codice MSIL, gli assembly pure presentano un comportamento più prevedibile e flessibile rispetto a quello degli assembly misti quando vengono utilizzati in applicazioni che ospitano il CLR e possono modificarne il comportamento predefinito.
Limitazioni di /clr:pure
In questa sezione vengono illustrate le funzionalità attualmente non supportate da /clr:pure.
Gli assembly pure non possono essere chiamati da funzioni non gestite.Di conseguenza, non possono implementare interfacce COM o esporre callback nativi.Agli assembly pure non è consentito esportare funzioni mediante file DEF o __declspec(dllexport).Non è inoltre possibile utilizzare __declspec(dllimport) per importare le funzioni dichiarate tramite la convenzione __clrcall.Le funzioni di un modulo nativo possono essere chiamate dagli assembly pure, che non possono, tuttavia, esporre funzioni chiamabili native. Di conseguenza, l'esposizione di funzionalità in un assembly pure deve essere eseguita mediante funzioni gestite di un assembly misto.Per ulteriori informazioni, vedere Procedura: migrare a /clr:pure (C++/CLI).
Le librerie ATL e MFC non sono supportate da una compilazione in modalità pure in Visual C++.
Pure .I file .netmodule non sono accettati come input dal linker Visual C++.che invece accetta i file obj pure. I file obj contengono un superset di informazioni presenti nei file netmodule.Per ulteriori informazioni, vedere .File con estensione netmodule come input del linker.
Il supporto del compilatore COM (#import) non viene fornito, poiché questo introdurrebbe istruzioni non gestite nell'assembly pure.
Le opzioni di virgola mobile per l'allineamento e la gestione delle eccezioni non sono modificabili per gli assembly pure.Di conseguenza, non è possibile utilizzare __declspec(align).Questo rende alcuni file di intestazione, ad esempio fpieee.h, incompatibili con /clr:pure.
La funzione GetLastError di PSDK può presentare un comportamento indefinito durante la compilazione con /clr:pure.
Verificabile (/clr:safe)
L'opzione del compilatore /clr:safe genera assembly verificabili, analoghi a quelli scritti in Visual Basic e C#, e conformi ai requisiti che consentono a CLR (Common Language Runtime) di garantire che il codice non violi le impostazioni di sicurezza correnti.Se ad esempio le impostazioni di sicurezza proibiscono a un componente di eseguire la scrittura su disco, CLR è in grado di controllare se un componente verificabile soddisfa tale criterio prima di eseguire qualsiasi parte del codice.Gli assembly verificabili non supportano CRT(tale supporto è disponibile per gli assembly pure grazie a una versione MSIL pure della libreria di runtime C).
Rispetto agli assembly pure e misti, gli assembly verificabili offrono i vantaggi seguenti:
Maggiore sicurezza.
In alcune situazioni, ad esempio per i componenti SQL, una maggiore sicurezza risulta necessaria.
Le versioni future di Windows richiederanno una sempre maggiore verificabilità di componenti e applicazioni.
Uno svantaggio è rappresentato dal fatto che le funzionalità di interoperabilità C++ non sono disponibili.Gli assembly verificabili non possono infatti contenere alcuna funzione non gestita o tipi di dati nativi, anche se il codice gestito non fa riferimento a essi.
Nonostante l'utilizzo del termine "safe" (sicura), la compilazione di applicazioni con /clr:safe non implica l'assenza di bug, ma significa solo che CLR è in grado di controllare le impostazioni di sicurezza in fase di esecuzione.
Indipendentemente dal tipo di assembly, le chiamate a DLL native eseguite da assembly gestiti tramite P/Invoke verranno compilate ma, a seconda delle impostazioni di sicurezza, potrebbero non riuscire in fase di esecuzione.
[!NOTA]
In un determinato scenario di codifica il passaggio del compilatore viene eseguito, ma viene generato un assembly non verificabile. Tale scenario è rappresentato dalla chiamata di una funzione virtuale tramite l'istanza di un oggetto utilizzando l'operatore di risoluzione dell'ambito.Ad esempio: MyObj -> A::VirtualFunction();.