Utilizzo delle funzionalità di interoperabilità C++ (PInvoke implicito)
A differenza degli altri linguaggi .NET, in Visual C++ viene fornito il supporto per l'interoperabilità che consente la presenza di codice gestito e codice non gestito nella stessa applicazione e persino nello stesso file (con le direttive pragma managed, unmanaged).Questo consente agli sviluppatori Visual C++ di integrare le funzionalità .NET nelle applicazioni Visual C++ esistenti, senza alcun impatto sul resto dell'applicazione.
È anche possibile chiamare funzioni non gestite da un modulo gestito utilizzando dllexport, dllimport.
L'utilizzo di PInvoke implicito è utile quando non occorre specificare il modo in cui verrà eseguito il marshalling dei parametri di funzione o quando gli eventuali altri dettagli possono essere specificati al momento della chiamata esplicita a DllImportAttribute.
In Visual C++ vengono forniti due modi per consentire l'interoperabilità tra le funzioni gestite e non gestite:
L'utilizzo di PInvoke esplicito è supportato da .NET Framework ed è disponibile nella maggior parte dei linguaggi .NET.Al contrario, l'interoperabilità C++ è specifica per il linguaggio Visual C++.
Interoperabilità C++
L'interoperabilità C++ è consigliata rispetto a PInvoke esplicito poiché fornisce un supporto indipendente dai tipi migliore, è in genere più semplice da implementare, crea meno problemi in caso di modifica dell'API non gestita e rende possibili miglioramenti in termini di prestazioni impensabili con PInvoke esplicito.L'interoperabilità C++, tuttavia, non è possibile se non è disponibile il codice sorgente non gestito o quando si esegue la compilazione con /clr:safe. Per ulteriori informazioni, vedere Codice pure e verificabile (C++/CLI).
Interoperabilità COM C++
Le funzionalità di interoperabilità supportate da Visual C++ offrono un particolare vantaggio rispetto agli altri linguaggi .NET quando vengono fornite per consentire l'interoperabilità con i componenti COM.Anziché essere vincolati alle restrizioni dell'Tlbimp.exe (utilità di importazione della libreria dei tipi) di .NET Framework, ad esempio il supporto limitato per i tipi di dati e l'esposizione obbligatoria di ciascun membro di ogni interfaccia COM, l'interoperabilità C++ consente infatti di accedere liberamente ai componenti COM e non richiede l'utilizzo di assembly di interoperabilità separati.Per ulteriori informazioni, vedere Using COM from .NET.
Tipi copiabili
Per le API non gestite che utilizzano tipi semplici intrinseci (vedere tipi copiabili e non copiabili) non è necessario alcun codice speciale, poiché questi tipi di dati hanno la stessa rappresentazione in memoria. I tipi di dati più complessi, invece, richiedono l'esecuzione esplicita del marshalling dei dati.Per un esempio, vedere Procedura: chiamare DLL native da codice gestito tramite PInvoke.
Esempio
// vcmcppv2_impl_dllimp.cpp
// compile with: /clr:pure user32.lib
using namespace System::Runtime::InteropServices;
// Implicit DLLImport specifying calling convention
extern "C" int __stdcall MessageBeep(int);
// explicit DLLImport needed here to use P/Invoke marshalling because
// System::String ^ is not the type of the first parameter to printf
[DllImport("msvcrt.dll", EntryPoint = "printf", CallingConvention = CallingConvention::Cdecl, CharSet = CharSet::Ansi)]
// or just
// [DllImport("msvcrt.dll")]
int printf(System::String ^, ...);
int main() {
// (string literals are System::String by default)
printf("Begin beep\n");
MessageBeep(100000);
printf("Done\n");
}
Argomenti della sezione
Procedura: Stringhe ANSI il marshalling utilizzando l'interoperabilità C++
Procedura: effettuare il marshalling di stringhe Unicode utilizzando l'interoperabilità C++
Procedura: Stringhe COM il marshalling utilizzando l'interoperabilità C++
Procedura: effettuare il marshalling di strutture utilizzando l'interoperabilità C++
Procedura: effettuare il marshalling di matrici utilizzando l'interoperabilità C++
Procedura: effettuare il marshalling di callback e delegati utilizzando l'interoperabilità C++
Procedura: effettuare il marshalling di puntatori incorporati utilizzando l'interoperabilità C++
Procedura: convertire una stringa char * in una matrice System::Byte
Procedura: caricare risorse non gestite in una matrice di byte
Procedura: modificare una classe di riferimenti in una funzione nativa
Procedura: mantenere riferimenti al tipo di valore nel tipo nativo
Procedura: mantenere i riferimenti agli oggetti nella memoria non gestita
Procedura: utilizzare un tipo nativo in una compilazione /clr
Procedura: eseguire il wrapping di una classe nativa affinché possa essere utilizzata in C#
Per informazioni sull'utilizzo dei delegati in uno scenario di interoperabilità, vedere delegato (Estensioni del componente C++).