Il presente articolo è stato tradotto automaticamente. Passare il puntatore sulle frasi nell'articolo per visualizzare il testo originale. Ulteriori informazioni.
Traduzione
Originale
Questo argomento non è stato ancora valutato - Valuta questo argomento

Interfaccia ICustomMarshaler

Fornisce wrapper personalizzati per la gestione delle chiamate a metodi.

Spazio dei nomi:  System.Runtime.InteropServices
Assembly:  mscorlib (in mscorlib.dll)
[ComVisibleAttribute(true)]
public interface ICustomMarshaler

Il tipo ICustomMarshaler espone i seguenti membri.

  NomeDescrizione
Metodo pubblicoSupportato da Libreria di classi portabileCleanUpManagedDataEsegue la necessaria eliminazione dei dati gestiti quando non sono più necessari.
Metodo pubblicoSupportato da Libreria di classi portabileCleanUpNativeDataEsegue la necessaria eliminazione dei dati non gestiti quando non sono più necessari.
Metodo pubblicoSupportato da Libreria di classi portabileGetNativeDataSizeRestituisce le dimensioni dei dati nativi di cui eseguire il marshalling.
Metodo pubblicoSupportato da Libreria di classi portabileMarshalManagedToNativeConverte i dati gestiti in dati non gestiti.
Metodo pubblicoSupportato da Libreria di classi portabileMarshalNativeToManagedConverte i dati non gestiti in dati gestiti.
In alto

Un gestore di marshalling costituisce un ponte tra le funzionalità della vecchia e della nuova interfaccia. Il marshalling personalizzato offre i seguenti vantaggi:

  • Consente di abilitare le applicazioni client progettate per interagire con un'interfaccia obsoleta al fine di funzionare anche con i server che implementano una nuova interfaccia.

  • Consente di abilitare le applicazioni client progettate per interagire con una nuova interfaccia al fine di funzionare con i server che implementano un'interfaccia obsoleta.

Se si dispone di un'interfaccia che introduce un comportamento diverso del gestore di marshalling o che è esposta a COM (Component Object Model) in modo diverso, è possibile progettare un gestore di marshalling personalizzato anziché utilizzare quello di interoperabilità. L'utilizzo di un gestore di marshalling personalizzato consente di ridurre al minimo le problematiche derivanti dalla diversità tra nuovi componenti .NET Framework e componenti COM esistenti.

Si immagini ad esempio di sviluppare un'interfaccia gestita denominata INew. Quando questa interfaccia viene esposta a COM tramite un oggetto COM Callable Wrapper (CCW) standard, dispone degli stessi metodi dell'interfaccia gestita e utilizza le regole di marshalling incorporate nel gestore di marshalling di interoperabilità. Si immagini ora che un'interfaccia COM nota denominata IOld fornisca già le stesse funzionalità dell'interfaccia INew. Progetta un gestore di marshalling personalizzato, è possibile fornire un'implementazione non gestita IOld che rimanda semplicemente le chiamate l'implementazione gestita dell'interfaccia INew. Pertanto, il gestore di marshalling personalizzato funge da ponte tra le interfacce gestita e non gestita.

NotaNota

I gestori di marshalling personalizzati non vengono richiamati dal lato del codice gestito al lato non gestito in un'interfaccia di solo invio.

Definizione del tipo di marshalling

Prima di compilare un gestore di marshalling personalizzato, è necessario stabilire su quali interfacce gestite e non gestite dovrà agire. Tali interfacce svolgono solitamente la stessa funzione, ma sono esposte in modo diverso, l'una a oggetti gestiti, l'altra a oggetti non gestiti.

Un compilatore gestito utilizza metadati per produrre un'interfaccia gestita. L'interfaccia risultante appare come qualsiasi altra interfaccia gestita. Nell'esempio seguente viene illustrata un'interfaccia tipica.


public interface INew
{
    void NewMethod();
}


Il tipo non gestito viene definito con il linguaggio di definizione dell'interfaccia (IDL, Interface Definition Language) e compilato con il compilatore MIDL (Microsoft Interface Definition Language). Viene definita l'interfaccia all'interno di un'istruzione di libreria e le viene assegnato un ID di interfaccia con l'attributo UUID (Universal Unique Identifier), come indicato nell'esempio seguente.

 [uuid(9B2BAADA-0705-11D3-A0CD-00C04FA35826)]
library OldLib {
     [uuid(9B2BAADD-0705-11D3-A0CD-00C04FA35826)]
     interface IOld : IUnknown
         HRESULT OldMethod();
}

Il compilatore MIDL produce diversi file di output. Se l'interfaccia è definita in Old.idl, nel file di output Old_i.c verrà definita una variabile const con l'IID (identificatore di interfaccia) come dimostra l'esempio seguente.

const IID IID_IOld = {0x9B2BAADD,0x0705,0x11D3,{0xA0,0xCD,0x00,0xC0,0x4F,0xA3,0x58,0x26}};

Anche il file Old.h viene prodotto da MIDL. Contiene una definizione C++ dell'interfaccia che può essere inclusa nel proprio codice sorgente C++.

Implementazione dell'interfaccia ICustomMarshaler

Il gestore di marshalling personalizzato deve implementare l'interfaccia ICustomMarshaler per fornire i wrapper appropriati al runtime.

Nel codice C# seguente viene visualizzata l'interfaccia di base che deve essere implementata da tutti i gestori di marshalling personalizzati.


public interface ICustomMarshaler
{
     Object MarshalNativeToManaged( IntPtr pNativeData );
     IntPtr MarshalManagedToNative( Object ManagedObj );
     void CleanUpNativeData( IntPtr pNativeData );
     void CleanUpManagedData( Object ManagedObj );
     int GetNativeDataSize();
}


L'interfaccia ICustomMarshaler comprende metodi che forniscono il supporto di conversione, di pulizia e le informazioni sui dati di cui effettuare il marshalling.

Tipo di operazione

Metodo ICustomMarshaler

Descrizione

Conversione (da codice nativo a codice gestito)

MarshalNativeToManaged

Effettua il marshalling di un puntatore ai dati nativi in un oggetto gestito. Questo metodo restituisce un oggetto Runtime Callable Wrapper (RCW) personalizzato in grado di effettuare il marshalling dell'interfaccia non gestita passata come argomento. Il gestore di marshalling deve restituire un'istanza dell'oggetto RCW personalizzato per il tipo.

Conversione (da codice gestito a codice nativo)

MarshalManagedToNative

Effettua il marshalling di un oggetto gestito in un puntatore ai dati nativi. Questo metodo restituisce un oggetto COM Callable Wrapper (CCW) personalizzato in grado di effettuare il marshalling dell'interfaccia gestita passata come argomento. Il gestore di marshalling deve restituire un'istanza dell'oggetto CCW personalizzato per il tipo.

Pulizia (di codice nativo)

CleanUpNativeData

Consente al gestore di marshalling di eseguire la pulizia dei dati nativi (CCW) restituiti dal metodo MarshalManagedToNative.

Pulizia (di codice gestito)

CleanUpManagedData

Consente al gestore di marshalling di eseguire la pulizia dei dati gestiti (RCW) restituiti dal metodo MarshalNativeToManaged.

Informazioni (sul codice nativo)

GetNativeDataSize

Restituisce le dimensioni dei dati non gestiti di cui effettuare il marshalling.

zk0a8dea.collapse_all(it-it,VS.110).gifConversion

ICustomMarshaler.MarshalNativeToManaged

Effettua il marshalling di un puntatore ai dati nativi in un oggetto gestito. Questo metodo restituisce un oggetto Runtime Callable Wrapper (RCW) personalizzato in grado di effettuare il marshalling dell'interfaccia non gestita passata come argomento. Il gestore di marshalling deve restituire un'istanza dell'oggetto RCW personalizzato per il tipo.

ICustomMarshaler.MarshalManagedToNative

Effettua il marshalling di un oggetto gestito in un puntatore ai dati nativi. Questo metodo restituisce un oggetto COM Callable Wrapper (CCW) personalizzato in grado di effettuare il marshalling dell'interfaccia gestita passata come argomento. Il gestore di marshalling deve restituire un'istanza dell'oggetto CCW personalizzato per il tipo.

zk0a8dea.collapse_all(it-it,VS.110).gifPulizia

ICustomMarshaler.CleanUpNativeData

Consente al gestore di marshalling di eseguire la pulizia dei dati nativi (CCW) restituiti dal metodo MarshalManagedToNative.

ICustomMarshaler.CleanUpManagedData

Consente al gestore di marshalling di eseguire la pulizia dei dati gestiti (RCW) restituiti dal metodo MarshalNativeToManaged.

zk0a8dea.collapse_all(it-it,VS.110).gifInformazioni sulle dimensioni

ICustomMarshaler.GetNativeDataSize

Restituisce le dimensioni dei dati non gestiti di cui effettuare il marshalling.

Implementazione del metodo GetInstance

Oltre a implementare l'interfaccia ICustomMarshaler, i gestori di marshalling personalizzati devono implementare un metodo static denominato GetInstance che accetta un String come parametro e il cui tipo restituito è ICustomMarshaler. Questo metodo static viene chiamato dal livello di interoperabilità COM di Common Language Runtime per creare un'istanza del gestore di marshalling personalizzato. La stringa passata a GetInstance è un cookie che il metodo può utilizzare per personalizzare il gestore di marshalling personalizzato restituito.

static ICustomMarshaler *GetInstance(String *pstrCookie);

Applicazione di MarshalAsAttribute

Per utilizzare un gestore di marshalling personalizzato, applicare l'attributo MarshalAsAttribute al parametro o al campo di cui si desidera effettuare il marshalling.

È necessario inoltre passare il valore di enumerazione UnmanagedType.CustomMarshaler al costruttore MarshalAsAttribute. È necessario inoltre specificare il campo MarshalType con uno dei seguenti parametri denominati:

  • MarshalType (obbligatorio): nome completo di assembly del gestore di marshalling personalizzato. Il nome deve includere lo spazio dei nomi e la classe del gestore di marshalling personalizzato. Se il gestore di marshalling personalizzato non è definito nell'assembly in cui viene utilizzato, è necessario specificare il nome dell'assembly in cui è definito.

    NotaNota

    È possibile utilizzare il campo MarshalTypeRef invece del campo MarshalType. MarshalTypeRef prende un tipo che è più semplice specificare.

  • MarshalCookie (opzionale): un cookie passato al gestore di marshalling personalizzato. È possibile utilizzare il cookie per fornire ulteriori informazioni al gestore di marshalling personalizzato. Se, ad esempio, lo stesso gestore di marshalling viene utilizzato per fornire più wrapper, il cookie ne identificherà uno specifico. Il cookie viene passato al metodo GetInstance del gestore di marshalling.

L'attributo MarshalAsAttribute identifica il gestore di marshalling personalizzato in modo che quest'ultimo possa attivare il wrapper appropriato. Il servizio di interoperabilità di Common Language Runtime esamina quindi l'attributo e crea il gestore di marshalling personalizzato la prima volta in cui è necessario eseguire il marshalling dell'argomento (parametro o campo).

Il runtime chiama quindi i metodi MarshalNativeToManaged e MarshalManagedToNative nel gestore di marshalling personalizzato per attivare il wrapper corretto per la gestione della chiamata.

Utilizzo di un gestore di marshalling personalizzato

Quando il gestore di marshalling personalizzato è completo, può+ essere utilizzato come wrapper personalizzato per un determinato tipo. Nell'esempio seguente viene illustrata la definizione dell'interfaccia gestita IUserData:


interface IUserData
{
    void DoSomeStuff(INew pINew);
}


Nell'esempio riportato di seguito, l'interfaccia IUserData utilizza i gestori di marshalling NewOldMarshaler personalizzati per abilitare applicazioni client non gestite al fine di passare da un'interfaccia IOld al metodo DoSomeStuff. La descrizione gestita del metodo DoSomeStuff accetta un'interfaccia INew, come illustrato nel precedente esempio, mentre la versione non gestita di DoSomeStuff accetta un puntatore a interfaccia IOld, come illustrato nell'esempio seguente.

[uuid(9B2BAADA-0705-11D3-A0CD-00C04FA35826)]
library UserLib {
     [uuid(9B2BABCD-0705-11D3-A0CD-00C04FA35826)]
     interface IUserData : IUnknown
         HRESULT DoSomeStuff(IUnknown* pIOld);
}

La libreria dei tipi generata esportando la definizione gestita di IUserData restituisce la definizione non gestita illustrata in questo esempio, anziché la definizione standard. L'attributo MarshalAsAttribute applicato all'argomento INew nella definizione gestita del metodo DoSomeStuff indica che l'argomento utilizza un gestore di marshalling personalizzato, come illustrato nell'esempio riportato di seguito.


Imports System.Runtime.InteropServices



using System.Runtime.InteropServices;



using namespace System::Runtime::InteropServices;



Public Interface IUserData
    Sub DoSomeStuff( _
        <MarshalAs(UnmanagedType.CustomMarshaler, _
        MarshalType := "MyCompany.NewOldMarshaler")> pINew As INew)
End Interface



interface IUserData
{
    void DoSomeStuff(
        [MarshalAs(UnmanagedType.CustomMarshaler,
             MarshalType="MyCompany.NewOldMarshaler")]
        INew pINew
    );
}



public interface class IUserData
{
    void DoSomeStuff(
        [MarshalAs(UnmanagedType::CustomMarshaler,
             MarshalType="MyCompany.NewOldMarshaler")]
        INew^ pINew
    );
};


Negli esempi precedenti, il primo parametro fornito all'attributo MarshalAsAttribute è corrisponde al valore di enumerazione UnmanagedType.CustomMarshalerUnmanagedType.CustomMarshaler.

Il secondo parametro è il campo MarshalType che fornisce il nome completo di assembly del gestore di marshalling personalizzato. Questo nome consiste dello spazio dei nomi e della classe del gestore di marshalling personalizzato (MarshalType="MyCompany.NewOldMarshaler").

.NET Framework

Supportato in: 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Supportato in: 4, 3.5 SP1

Libreria di classi portabile

Supportato in: Libreria di classi portabile

Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (ruoli di base del server non supportati), Windows Server 2008 R2 (ruoli di base del server supportati con SP1 o versione successiva, Itanium non supportato)

.NET Framework non supporta tutte le versioni di ciascuna piattaforma. Per un elenco delle versioni supportate, vedere Requisiti di sistema di .NET Framework.
Il documento è risultato utile?
(1500 caratteri rimanenti)

Aggiunte alla community

AGGIUNGI
© 2013 Microsoft. Tutti i diritti riservati.