ICustomMarshaler ICustomMarshaler ICustomMarshaler ICustomMarshaler Interface

Definition

Stellt benutzerdefinierte Wrapper für die Behandlung von Methodenaufrufen bereit.Provides custom wrappers for handling method calls.

public interface class ICustomMarshaler
[System.Runtime.InteropServices.ComVisible(true)]
public interface ICustomMarshaler
type ICustomMarshaler = interface
Public Interface ICustomMarshaler
Abgeleitet
Attribute

Hinweise

Ein Mars Haller stellt eine Brücke zwischen der Funktionalität von alten und neuen Schnittstellen bereit.A marshaler provides a bridge between the functionality of old and new interfaces. Das benutzerdefinierte Marshalling bietet die folgenden Vorteile:Custom marshaling provides the following benefits:

  • Client Anwendungen, die für die Arbeit mit einer alten Schnittstelle entworfen wurden, können auch mit Servern arbeiten, die eine neue Schnittstelle implementieren.It enables client applications that were designed to work with an old interface to also work with servers that implement a new interface.

  • Dadurch können Client Anwendungen, die mit einer neuen Schnittstelle erstellt wurden, mit Servern arbeiten, die eine alte Schnittstelle implementieren.It enables client applications built to work with a new interface to work with servers that implement an old interface.

Wenn Sie über eine Schnittstelle verfügen, die unterschiedliche Marshallingverhalten einführt oder die für die Component Object Model (com) verfügbar gemacht wird, können Sie einen benutzerdefinierten Mars Haller entwerfen, anstatt den Interop-Mars Haller zu verwenden.If you have an interface that introduces different marshaling behavior or that is exposed to the Component Object Model (COM) in a different way, you can design a custom marshaler instead of using the interop marshaler. Mithilfe eines benutzerdefinierten Mars Haller können Sie den Unterschied zwischen neuen .NET Framework Komponenten und vorhandenen COM-Komponenten minimieren.By using a custom marshaler, you can minimize the distinction between new .NET Framework components and existing COM components.

Angenommen, Sie entwickeln eine verwaltete Schnittstelle mit dem Namen INew.For example, suppose that you are developing a managed interface called INew. Wenn diese Schnittstelle für com über einen Standard COM Callable Wrapper (CCW) verfügbar gemacht wird, verfügt sie über dieselben Methoden wie die verwaltete Schnittstelle und verwendet die marshallingregeln, die in den Interop-Mars Haller integriert sind.When this interface is exposed to COM through a standard COM callable wrapper (CCW), it has the same methods as the managed interface and uses the marshaling rules built into the interop marshaler. Angenommen, eine bekannte com-Schnittstelle mit dem IOld Namen bietet bereits die gleiche Funktionalität wie INew die-Schnittstelle.Now suppose that a well-known COM interface called IOld already provides the same functionality as the INew interface. Durch Entwerfen eines benutzerdefinierten Mars Haller können Sie eine nicht verwaltete Implementierung von IOld bereitstellen, die einfach die Aufrufe an die verwaltete Implementierung INew der-Schnittstelle delegiert.By designing a custom marshaler, you can provide an unmanaged implementation of IOld that simply delegates the calls to the managed implementation of the INew interface. Der benutzerdefinierte Mars Haller fungiert daher als Brücke zwischen den verwalteten und nicht verwalteten Schnittstellen.Therefore, the custom marshaler acts as a bridge between the managed and unmanaged interfaces.

Hinweis

Benutzerdefinierte Mars Haller werden nicht aufgerufen, wenn von verwaltetem Code an nicht verwalteten Code auf einer reinen Dispatch-Schnittstelle aufgerufen wird.Custom marshalers are not invoked when calling from managed code to unmanaged code on a dispatch-only interface.

Definieren des MarshallingtypsDefining the Marshaling Type

Bevor Sie einen benutzerdefinierten Mars Haller erstellen können, müssen Sie die verwalteten und nicht verwalteten Schnittstellen definieren, die gemarshallt werden.Before you can build a custom marshaler, you must define the managed and unmanaged interfaces that will be marshaled. Diese Schnittstellen führen in der Regel dieselbe Funktion aus, werden jedoch unterschiedlich für verwaltete und nicht verwaltete Objekte verfügbar gemacht.These interfaces commonly perform the same function but are exposed differently to managed and unmanaged objects.

Ein verwalteter Compiler erzeugt eine verwaltete Schnittstelle aus Metadaten, und die resultierende Schnittstelle sieht wie jede andere verwaltete Schnittstelle aus.A managed compiler produces a managed interface from metadata, and the resulting interface looks like any other managed interface. Das folgende Beispiel zeigt eine typische-Schnittstelle.The following example shows a typical interface.

public interface class INew
{
    void NewMethod();
};
public interface INew
{
    void NewMethod();
}
Public Interface INew
    Sub NewMethod()
End Interface

Sie definieren den nicht verwalteten Typ in der Interface Definition Language (IDL) und kompilieren ihn mit dem Microsoft Interface Definition Language (mittlerer l)-Compiler.You define the unmanaged type in Interface Definition Language (IDL) and compile it with the Microsoft Interface Definition Language (MIDL) compiler. Sie definieren die Schnittstelle innerhalb einer Bibliotheks Anweisung und weisen ihr eine Schnittstellen-ID mit dem Attribut Universal Unique Identifier (UUID) zu, wie im folgenden Beispiel veranschaulicht.You define the interface within a library statement and assign it an interface ID with the universal unique identifier (UUID) attribute, as the following example demonstrates.

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

Der mittlerer l-Compiler erzeugt mehrere Ausgabedateien.The MIDL compiler produces several output files. Wenn die Schnittstelle in Alter. idl definiert ist, definiert die Ausgabedatei Old_i. c const eine Variable mit dem Schnittstellen Bezeichner (Interface Identifier, IID) der Schnittstelle, wie im folgenden Beispiel veranschaulicht.If the interface is defined in Old.idl, the output file Old_i.c defines a const variable with the interface identifier (IID) of the interface, as the following example demonstrates.

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

Die alte h-Datei wird auch von "Mittel l" erstellt.The Old.h file is also produced by MIDL. Sie enthält eine C++ Definition der-Schnittstelle, die in den C++ Quellcode aufgenommen werden kann.It contains a C++ definition of the interface that can be included in your C++ source code.

Implementieren der ICustomMarshaler-SchnittstelleImplementing the ICustomMarshaler Interface

Der benutzerdefinierte Mars Haller muss die ICustomMarshaler -Schnittstelle implementieren, um die entsprechenden Wrapper zur Laufzeit bereitzustellen.Your custom marshaler must implement the ICustomMarshaler interface to provide the appropriate wrappers to the runtime.

Im folgenden C# Code wird die Basisschnittstelle angezeigt, die von allen benutzerdefinierten Mars Haller implementiert werden muss.The following C# code displays the base interface that must be implemented by all custom marshalers.

public interface class ICustomMarshaler
{
     Object^ MarshalNativeToManaged( IntPtr^ pNativeData );
     IntPtr^ MarshalManagedToNative( Object^ ManagedObj );
     void CleanUpNativeData( IntPtr^ pNativeData );
     void CleanUpManagedData( Object^ ManagedObj );
     int GetNativeDataSize();
};
public interface ICustomMarshaler
{
     Object MarshalNativeToManaged( IntPtr pNativeData );
     IntPtr MarshalManagedToNative( Object ManagedObj );
     void CleanUpNativeData( IntPtr pNativeData );
     void CleanUpManagedData( Object ManagedObj );
     int GetNativeDataSize();
}
Public Interface ICustomMarshaler
     Function MarshalNativeToManaged( pNativeData As IntPtr ) As Object
     Function MarshalManagedToNative( ManagedObj As Object ) As IntPtr
     Sub CleanUpNativeData( pNativeData As IntPtr )
     Sub CleanUpManagedData( ManagedObj As Object )
     Function GetNativeDataSize() As Integer
End Interface

Die ICustomMarshaler -Schnittstelle enthält Methoden, die Konvertierungs Unterstützung, cleanupunterstützung und Informationen zu den zu marshallten Daten bereitstellen.The ICustomMarshaler interface includes methods that provide conversion support, cleanup support, and information about the data to be marshaled.

Typ des VorgangsType of operation ICustomMarshaler-MethodeICustomMarshaler method BeschreibungDescription
Konvertierung (von nativem in verwalteten Code)Conversion (from native to managed code) MarshalNativeToManaged Marshalls einen Zeiger auf systemeigene Daten in ein verwaltetes-Objekt.Marshals a pointer to native data into a managed object. Diese Methode gibt eine benutzerdefinierte Runtime Callable Wrapper (RCW) zurück, die die nicht verwaltete Schnittstelle Mars Hallen kann, die als Argument übermittelt wird.This method returns a custom runtime callable wrapper (RCW) that can marshal the unmanaged interface that is passed as an argument. Der Mars Haller sollte eine Instanz des benutzerdefinierten RCW für diesen Typ zurückgeben.The marshaler should return an instance of the custom RCW for that type.
Konvertierung (von verwaltetem zu nativem Code)Conversion (from managed to native code) MarshalManagedToNative Marshalls ein verwaltetes Objekt in einen Zeiger auf systemeigene Daten.Marshals a managed object into a pointer to native data. Diese Methode gibt eine benutzerdefinierte COM Callable Wrapper (CCW) zurück, die die als Argument übergebenen verwaltete Schnittstelle Mars Hallen kann.This method returns a custom COM callable wrapper (CCW) that can marshal the managed interface that is passed as an argument. Der Mars Haller sollte eine Instanz des benutzerdefinierten CCW für diesen Typ zurückgeben.The marshaler should return an instance of the custom CCW for that type.
Cleanup (von nativem Code)Cleanup (of native code) CleanUpNativeData Ermöglicht dem Mars Haller das Bereinigen der systemeigenen Daten (der CCW), die von der MarshalManagedToNative -Methode zurückgegeben werden.Enables the marshaler to clean up the native data (the CCW) that is returned by the MarshalManagedToNative method.
Cleanup (verwalteter Code)Cleanup (of managed code) CleanUpManagedData Ermöglicht dem Mars Haller das Bereinigen der verwalteten Daten (RCW), die von der MarshalNativeToManaged -Methode zurückgegeben werden.Enables the marshaler to clean up the managed data (the RCW) that is returned by the MarshalNativeToManaged method.
Informationen (Informationen zu nativem Code)Information (about native code) GetNativeDataSize Gibt die Größe der nicht verwalteten Daten zurück, die gemarshallt werden sollen.Returns the size of the unmanaged data to be marshaled.

UmwandelnConversion

ICustomMarshaler.MarshalNativeToManaged

Marshalls einen Zeiger auf systemeigene Daten in ein verwaltetes-Objekt.Marshals a pointer to native data into a managed object. Diese Methode gibt eine benutzerdefinierte Runtime Callable Wrapper (RCW) zurück, die die nicht verwaltete Schnittstelle Mars Hallen kann, die als Argument übermittelt wird.This method returns a custom runtime callable wrapper (RCW) that can marshal the unmanaged interface that is passed as an argument. Der Mars Haller sollte eine Instanz des benutzerdefinierten RCW für diesen Typ zurückgeben.The marshaler should return an instance of the custom RCW for that type.

ICustomMarshaler.MarshalManagedToNative

Marshalls ein verwaltetes Objekt in einen Zeiger auf systemeigene Daten.Marshals a managed object into a pointer to native data. Diese Methode gibt eine benutzerdefinierte COM Callable Wrapper (CCW) zurück, die die als Argument übergebenen verwaltete Schnittstelle Mars Hallen kann.This method returns a custom COM callable wrapper (CCW) that can marshal the managed interface that is passed as an argument. Der Mars Haller sollte eine Instanz des benutzerdefinierten CCW für diesen Typ zurückgeben.The marshaler should return an instance of the custom CCW for that type.

BereinigungCleanup

ICustomMarshaler.CleanUpNativeData

Ermöglicht dem Mars Haller das Bereinigen der systemeigenen Daten (der CCW), die von der MarshalManagedToNative -Methode zurückgegeben werden.Enables the marshaler to clean up the native data (the CCW) that is returned by the MarshalManagedToNative method.

ICustomMarshaler.CleanUpManagedData

Ermöglicht dem Mars Haller das Bereinigen der verwalteten Daten (RCW), die von der MarshalNativeToManaged -Methode zurückgegeben werden.Enables the marshaler to clean up the managed data (the RCW) that is returned by the MarshalNativeToManaged method.

Größen InformationenSize Information

ICustomMarshaler.GetNativeDataSize

Gibt die Größe der nicht verwalteten Daten zurück, die gemarshallt werden sollen.Returns the size of the unmanaged data to be marshaled.

Implementieren der GetInstance-MethodeImplementing the GetInstance Method

Neben der Implementierung der- ICustomMarshaler Schnittstelle müssen benutzerdefinierte Marshalling eine static Methode mit dem GetInstance Namen implementieren, String die einen als Parameter akzeptiert und den Rückgabetyp ICustomMarshaleraufweist.In addition to implementing the ICustomMarshaler interface, custom marshalers must implement a static method called GetInstance that accepts a String as a parameter and has a return type of ICustomMarshaler. Diese static Methode wird von der COM-Interop-Ebene des Common Language Runtime aufgerufen, um eine Instanz des benutzerdefinierten Mars Haller zu instanziieren.This static method is called by the common language runtime's COM interop layer to instantiate an instance of the custom marshaler. Die an GetInstance übergebene Zeichenfolge ist ein Cookie, das von der-Methode zum Anpassen des zurückgegebenen benutzerdefinierten Mars Haller verwendet werden kann.The string that is passed to GetInstance is a cookie that the method can use to customize the returned custom marshaler.

static ICustomMarshaler *GetInstance(String *pstrCookie);  

Anwenden von MarshalAsAttributeApplying MarshalAsAttribute

Wenn Sie einen benutzerdefinierten Mars Haller verwenden möchten, müssen Sie MarshalAsAttribute das-Attribut auf den Parameter oder das Feld anwenden, das gemarshallt wird.To use a custom marshaler, you must apply the MarshalAsAttribute attribute to the parameter or field that is being marshaled.

Außerdem müssen Sie den UnmanagedType.CustomMarshaler -Enumerationswert an den MarshalAsAttribute -Konstruktor übergeben.You must also pass the UnmanagedType.CustomMarshaler enumeration value to the MarshalAsAttribute constructor. Außerdem müssen Sie das MarshalType Feld mit einem der folgenden benannten Parameter angeben:In addition, you must specify the MarshalType field with one of the following named parameters:

  • MarshalType(erforderlich): Der durch die Assembly qualifizierte Name des benutzerdefinierten Mars Haller.MarshalType (required): The assembly-qualified name of the custom marshaler. Der Name muss den Namespace und die Klasse des benutzerdefinierten Mars Haller enthalten.The name should include the namespace and class of the custom marshaler. Wenn der benutzerdefinierte Mars Haller nicht in der Assembly definiert ist, in der er verwendet wird, müssen Sie den Namen der Assembly angeben, in der er definiert ist.If the custom marshaler is not defined in the assembly it is used in, you must specify the name of the assembly in which it is defined.

    Hinweis

    Sie können das MarshalTypeRef -Feld anstelle MarshalType des-Felds verwenden.You can use the MarshalTypeRef field instead of the MarshalType field. MarshalTypeRefnimmt einen Typ an, der einfacher angegeben werden kann.MarshalTypeRef takes a type that is easier to specify.

  • MarshalCookie(optional): Ein Cookie, das an den benutzerdefinierten Mars Haller übergebenen wird.MarshalCookie (optional): A cookie that is passed to the custom marshaler. Sie können das Cookie verwenden, um dem Mars Haller zusätzliche Informationen bereitzustellen.You can use the cookie to provide additional information to the marshaler. Wenn z. b. derselbe Mars Haller verwendet wird, um eine Reihe von Wrappern bereitzustellen, identifiziert das Cookie einen bestimmten Wrapper.For example, if the same marshaler is used to provide a number of wrappers, the cookie identifies a specific wrapper. Das Cookie wird an die GetInstance -Methode des Mars Haller-Diensts übermittelt.The cookie is passed to the GetInstance method of the marshaler.

Das MarshalAsAttribute -Attribut identifiziert den benutzerdefinierten Mars Haller, sodass er den passenden Wrapper aktivieren kann.The MarshalAsAttribute attribute identifies the custom marshaler so it can activate the appropriate wrapper. Der Interop-Dienst des Common Language Runtime überprüft dann das Attribut und erstellt den benutzerdefinierten Mars Haller, wenn das Argument (Parameter oder Feld) zum ersten Mal gemarshallt werden muss.The common language runtime's interop service then examines the attribute and creates the custom marshaler the first time the argument (parameter or field) needs to be marshaled.

Die Runtime ruft dann die MarshalNativeToManaged - MarshalManagedToNative Methode und die-Methode für den benutzerdefinierten Mars Haller auf, um den korrekten Wrapper zur Behandlung des Aufrufs zu aktivieren.The runtime then calls the MarshalNativeToManaged and MarshalManagedToNative methods on the custom marshaler to activate the correct wrapper to handle the call.

Verwenden eines benutzerdefinierten Mars HallerUsing a Custom Marshaler

Wenn der benutzerdefinierte Mars Haller vollständig ist, können Sie ihn als benutzerdefinierten Wrapper für einen bestimmten Typ verwenden.When the custom marshaler is complete, you can use it as a custom wrapper for a particular type. Das folgende Beispiel zeigt die Definition IUserData der verwalteten Schnittstelle:The following example shows the definition of the IUserData managed interface:

public interface class IUserData
{
    void DoSomeStuff(INew^ pINew);
};
interface IUserData
{
    void DoSomeStuff(INew pINew);
}
Public Interface IUserData
    Sub DoSomeStuff(pINew As INew)
End Interface

Im folgenden Beispiel verwendet IUserData die-Schnittstelle den NewOldMarshaler benutzerdefinierten Mars Haller, um zu ermöglichen, dass nicht verwaltete Client Anwendungen eine IOld Schnitt DoSomeStuff Stelle an die-Methode übergeben.In the following example, the IUserData interface uses the NewOldMarshaler custom marshaler to enable unmanaged client applications to pass an IOld interface to the DoSomeStuff method. DoSomeStuff Die verwaltete Beschreibung der Methode übernimmt eine INew Schnittstelle, wie im vorherigen Beispiel gezeigt, wohingegen die nicht verwaltete Version von DoSomeStuff einen IOld Schnittstellen Zeiger annimmt, wie im folgenden Beispiel gezeigt.The managed description of the DoSomeStuff method takes an INew interface, as shown in the previous example, whereas the unmanaged version of DoSomeStuff takes an IOld interface pointer, as shown in the following example.

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

Die Typbibliothek, die durch Exportieren der verwalteten Definition von IUserData generiert wird, ergibt die nicht verwaltete Definition, die in diesem Beispiel anstelle der Standard Definition angezeigt wird.The type library that is generated by exporting the managed definition of IUserData yields the unmanaged definition shown in this example instead of the standard definition. Das MarshalAsAttribute -Attribut, das INew auf das-Argument in DoSomeStuff der verwalteten Definition der-Methode angewendet wird, gibt an, dass das-Argument einen benutzerdefinierten Mars Haller verwendet, wie im folgenden Beispiel gezeigt.The MarshalAsAttribute attribute applied to the INew argument in the managed definition of the DoSomeStuff method indicates that the argument uses a custom marshaler, as the following example shows.

using namespace System::Runtime::InteropServices;
using System.Runtime.InteropServices;
Imports System.Runtime.InteropServices
public interface class IUserData
{
    void DoSomeStuff(
        [MarshalAs(UnmanagedType::CustomMarshaler,
             MarshalType="MyCompany.NewOldMarshaler")]
        INew^ pINew
    );
};
interface IUserData
{
    void DoSomeStuff(
        [MarshalAs(UnmanagedType.CustomMarshaler,
             MarshalType="MyCompany.NewOldMarshaler")]
        INew pINew
    );
}
Public Interface IUserData
    Sub DoSomeStuff( _
        <MarshalAs(UnmanagedType.CustomMarshaler, _
        MarshalType := "MyCompany.NewOldMarshaler")> pINew As INew)
End Interface

In den vorherigen Beispielen ist der erste Parameter, der für MarshalAsAttribute das-Attribut UnmanagedType.CustomMarshaler bereitgestellt wird UnmanagedType.CustomMarshaler, der-Enumerationswert.In the previous examples, the first parameter provided to the MarshalAsAttribute attribute is the UnmanagedType.CustomMarshaler enumeration value UnmanagedType.CustomMarshaler.

Der zweite Parameter ist das MarshalType Feld, das den durch die Assembly qualifizierten Namen des benutzerdefinierten Mars Haller bereitstellt.The second parameter is the MarshalType field, which provides the assembly-qualified name of the custom marshaler. Dieser Name besteht aus dem-Namespace und der-Klasse des benutzerdefinierten MarsMarshalType="MyCompany.NewOldMarshaler"Haller ().This name consists of the namespace and class of the custom marshaler (MarshalType="MyCompany.NewOldMarshaler").

Methoden

CleanUpManagedData(Object) CleanUpManagedData(Object) CleanUpManagedData(Object) CleanUpManagedData(Object)

Führt die notwendigen Bereinigungsvorgänge für verwaltete Daten durch, wenn diesen nicht mehr benötigt werden.Performs necessary cleanup of the managed data when it is no longer needed.

CleanUpNativeData(IntPtr) CleanUpNativeData(IntPtr) CleanUpNativeData(IntPtr) CleanUpNativeData(IntPtr)

Führt die notwendigen Bereinigungsvorgänge für nicht verwaltete Daten durch, wenn diesen nicht mehr benötigt werden.Performs necessary cleanup of the unmanaged data when it is no longer needed.

GetNativeDataSize() GetNativeDataSize() GetNativeDataSize() GetNativeDataSize()

Gibt die Größe der systemeigenen Daten zurück, die gemarshallt werden sollen.Returns the size of the native data to be marshaled.

MarshalManagedToNative(Object) MarshalManagedToNative(Object) MarshalManagedToNative(Object) MarshalManagedToNative(Object)

Konvertiert verwaltete in nicht verwaltete Daten.Converts the managed data to unmanaged data.

MarshalNativeToManaged(IntPtr) MarshalNativeToManaged(IntPtr) MarshalNativeToManaged(IntPtr) MarshalNativeToManaged(IntPtr)

Konvertiert verwaltete in nicht verwaltete Daten.Converts the unmanaged data to managed data.

Gilt für: