Utilizzo delle funzionalità di interoperabilità C++ (PInvoke implicito)
Aggiornamento: novembre 2007
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.
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'Utilità di importazione della libreria dei tipi (Tlbimp.exe) 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 Utilizzo di server COM nativi da .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");
}
Begin beep
Done
In questa sezione
Procedura: effettuare il marshalling di stringhe ANSI utilizzando l'interoperabilità C++
Procedura: effettuare il marshalling di stringhe Unicode utilizzando l'interoperabilità C++
Procedura: effettuare il marshalling di stringhe COM 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 in una funzione nativa
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 delegate.