ICustomMarshaler 인터페이스

정의

메서드 호출 처리를 위한 사용자 지정 래퍼를 제공합니다.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
파생
특성

설명

마샬러는 새 인터페이스와 이전 기능 간에 브리지를 제공합니다.A marshaler provides a bridge between the functionality of old and new interfaces. 사용자 지정 마샬링 다음과 같은 이점이 있습니다.Custom marshaling provides the following benefits:

  • 또한 새 인터페이스를 구현 하는 서버로 작업 하도록 이전 인터페이스와 함께 작동 하도록 설계 된 클라이언트 애플리케이션 수 있습니다.It enables client applications that were designed to work with an old interface to also work with servers that implement a new interface.

  • 클라이언트 애플리케이션을 새 인터페이스를 사용 하 여 작동 하도록 빌드된 이전 인터페이스를 구현 하는 서버를 작업할 수 있습니다.It enables client applications built to work with a new interface to work with servers that implement an old interface.

구성 요소 개체 모델 (COM)를 다른 방식으로 노출 되는 다양 한 마샬링 동작을 제공 하는 인터페이스에 있는 경우 interop 마샬러를 사용 하는 대신 사용자 지정 마샬러를 디자인할 수 있습니다.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. 사용자 지정 마샬러를 사용 하 여 새.NET Framework 구성 요소와 기존 COM 구성 요소 간 구분을 최소화할 수 있습니다.By using a custom marshaler, you can minimize the distinction between new .NET Framework components and existing COM components.

예를 들어 INew라는 관리 되는 인터페이스를 개발 한다고 가정 합니다.For example, suppose that you are developing a managed interface called INew. COM에는 표준 COM 호출 가능 래퍼 (CCW)를 통해이 인터페이스를 노출 하는 경우 관리 되는 인터페이스와 동일한 메서드를 포함 하 고 interop 마샬러가에 기본 제공 마샬링 규칙을 사용 합니다.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. 이제 IOld 이라는 잘 알려진 COM 인터페이스가 이미 INew 인터페이스와 동일한 기능을 제공 한다고 가정 합니다.Now suppose that a well-known COM interface called IOld already provides the same functionality as the INew interface. 사용자 지정 마샬러를 디자인 하 여 INew 인터페이스의 관리 되는 구현에 대 한 호출만 위임 하는 IOld의 관리 되지 않는 구현을 제공할 수 있습니다.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. 따라서 사용자 지정 마샬러는 관리 및 관리 되지 않는 인터페이스 간의 다리 역할입니다.Therefore, the custom marshaler acts as a bridge between the managed and unmanaged interfaces.

참고

디스패치 전용 인터페이스에서 관리 코드에서 비관리 코드를 호출 하는 경우에 사용자 지정 마샬러 호출 되지 않습니다.Custom marshalers are not invoked when calling from managed code to unmanaged code on a dispatch-only interface.

마샬링 형식 정의Defining the Marshaling Type

사용자 지정 마샬러를 작성 하기 전에 마샬링할 수는 관리 및 관리 되지 않는 인터페이스를 정의 해야 합니다.Before you can build a custom marshaler, you must define the managed and unmanaged interfaces that will be marshaled. 이러한 인터페이스는 일반적으로 동일한 기능을 수행 하지만 관리 및 관리 되지 않는 개체에 다르게 노출 됩니다.These interfaces commonly perform the same function but are exposed differently to managed and unmanaged objects.

관리 되는 컴파일러에서 메타 데이터에서 관리 되는 인터페이스 및 결과 인터페이스는 다른 관리 되는 인터페이스와 같습니다.A managed compiler produces a managed interface from metadata, and the resulting interface looks like any other managed interface. 다음 예제에서는 일반적인 인터페이스를 보여 줍니다.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

관리 되지 않는 형식에서 IDL Interface Definition Language ()를 정의 하 고 인터페이스 정의 언어 (MIDL (Microsoft) 컴파일러를 사용 하 여 컴파일.You define the unmanaged type in Interface Definition Language (IDL) and compile it with the Microsoft Interface Definition Language (MIDL) compiler. 라이브러리 문 내에서 인터페이스를 정의 하 고 다음 예제 에서처럼 범용 고유 식별자 (UUID) 특성을 사용 하 여 인터페이스 ID를 할당 합니다.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();  
}  

MIDL 컴파일러 여러 출력 파일을 생성합니다.The MIDL compiler produces several output files. 인터페이스가 이전 .idl에서 정의 되는 경우 출력 파일 Old_i는 다음 예제와 같이 인터페이스의 IID (인터페이스 식별자)를 사용 하 여 const 변수를 정의 합니다.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}};  

Old.h 파일은 또한 MIDL에서 생성 됩니다.The Old.h file is also produced by MIDL. C + + 소스 코드에 포함 될 수 있는 인터페이스의 c + + 정의 포함 합니다.It contains a C++ definition of the interface that can be included in your C++ source code.

ICustomMarshaler 인터페이스 구현Implementing the ICustomMarshaler Interface

사용자 지정 마샬러는 런타임에 적절 한 래퍼를 제공 하기 위해 ICustomMarshaler 인터페이스를 구현 해야 합니다.Your custom marshaler must implement the ICustomMarshaler interface to provide the appropriate wrappers to the runtime.

다음 C# 코드는 모든 사용자 지정 마샬러 구현 해야 하는 기본 인터페이스를 표시 합니다.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

ICustomMarshaler 인터페이스에는 변환 지원, 정리 지원 및 마샬링할 데이터에 대 한 정보를 제공 하는 메서드가 포함 되어 있습니다.The ICustomMarshaler interface includes methods that provide conversion support, cleanup support, and information about the data to be marshaled.

작업의 형식Type of operation ICustomMarshaler 메서드ICustomMarshaler method 설명Description
(관리 코드에 네이티브) 코드에서 변환Conversion (from native to managed code) MarshalNativeToManaged 관리 되는 개체에 네이티브 데이터에 대 한 포인터를 마샬링합니다.Marshals a pointer to native data into a managed object. 이 메서드는 사용자 지정 런타임 호출 가능 래퍼 (RCW)는 인수로 전달 되는 관리 되지 않는 인터페이스를 마샬링할 수를 반환 합니다.This method returns a custom runtime callable wrapper (RCW) that can marshal the unmanaged interface that is passed as an argument. 마샬러는 해당 형식에 대 한 사용자 지정 RCW의 인스턴스를 반환 해야 합니다.The marshaler should return an instance of the custom RCW for that type.
변환 (에서 네이티브 코드)Conversion (from managed to native code) MarshalManagedToNative 네이티브 데이터에 대 한 관리 되는 개체를 마샬링합니다.Marshals a managed object into a pointer to native data. 이 메서드는 사용자 지정 COM 호출 가능 래퍼 (CCW) 인수로 전달 되는 관리 되는 인터페이스를 마샬링할 수 있는 반환 합니다.This method returns a custom COM callable wrapper (CCW) that can marshal the managed interface that is passed as an argument. 마샬러는 해당 형식에 대 한 사용자 지정 CCW의 인스턴스를 반환 해야 합니다.The marshaler should return an instance of the custom CCW for that type.
네이티브 코드 정리Cleanup (of native code) CleanUpNativeData 마샬러에서 MarshalManagedToNative 메서드에서 반환 되는 네이티브 데이터 (CCW)를 정리할 수 있도록 합니다.Enables the marshaler to clean up the native data (the CCW) that is returned by the MarshalManagedToNative method.
관리 되는 코드 정리Cleanup (of managed code) CleanUpManagedData 마샬러에서 MarshalNativeToManaged 메서드에서 반환 된 관리 되는 데이터 (RCW)를 정리할 수 있도록 합니다.Enables the marshaler to clean up the managed data (the RCW) that is returned by the MarshalNativeToManaged method.
(네이티브 코드용)에 대 한 정보Information (about native code) GetNativeDataSize 마샬링될 관리 되지 않는 데이터의 크기를 반환 합니다.Returns the size of the unmanaged data to be marshaled.

변환Conversion

ICustomMarshaler.MarshalNativeToManaged

관리 되는 개체에 네이티브 데이터에 대 한 포인터를 마샬링합니다.Marshals a pointer to native data into a managed object. 이 메서드는 사용자 지정 런타임 호출 가능 래퍼 (RCW)는 인수로 전달 되는 관리 되지 않는 인터페이스를 마샬링할 수를 반환 합니다.This method returns a custom runtime callable wrapper (RCW) that can marshal the unmanaged interface that is passed as an argument. 마샬러는 해당 형식에 대 한 사용자 지정 RCW의 인스턴스를 반환 해야 합니다.The marshaler should return an instance of the custom RCW for that type.

ICustomMarshaler.MarshalManagedToNative

네이티브 데이터에 대 한 관리 되는 개체를 마샬링합니다.Marshals a managed object into a pointer to native data. 이 메서드는 사용자 지정 COM 호출 가능 래퍼 (CCW) 인수로 전달 되는 관리 되는 인터페이스를 마샬링할 수 있는 반환 합니다.This method returns a custom COM callable wrapper (CCW) that can marshal the managed interface that is passed as an argument. 마샬러는 해당 형식에 대 한 사용자 지정 CCW의 인스턴스를 반환 해야 합니다.The marshaler should return an instance of the custom CCW for that type.

정리Cleanup

ICustomMarshaler.CleanUpNativeData

마샬러에서 MarshalManagedToNative 메서드에서 반환 되는 네이티브 데이터 (CCW)를 정리할 수 있도록 합니다.Enables the marshaler to clean up the native data (the CCW) that is returned by the MarshalManagedToNative method.

ICustomMarshaler.CleanUpManagedData

마샬러에서 MarshalNativeToManaged 메서드에서 반환 된 관리 되는 데이터 (RCW)를 정리할 수 있도록 합니다.Enables the marshaler to clean up the managed data (the RCW) that is returned by the MarshalNativeToManaged method.

크기 정보Size Information

ICustomMarshaler.GetNativeDataSize

마샬링될 관리 되지 않는 데이터의 크기를 반환 합니다.Returns the size of the unmanaged data to be marshaled.

GetInstance 메서드를 구현합니다.Implementing the GetInstance Method

ICustomMarshaler 인터페이스를 구현 하는 것 외에도 사용자 지정 마샬러는 String를 매개 변수로 받아들이고 ICustomMarshaler의 반환 형식을 갖는 GetInstance 이라는 static 메서드를 구현 해야 합니다.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. static 메서드는 사용자 지정 마샬러의 인스턴스를 인스턴스화하기 위해 공용 언어 런타임의 COM interop 계층에 의해 호출 됩니다.This static method is called by the common language runtime's COM interop layer to instantiate an instance of the custom marshaler. GetInstance 전달 되는 문자열은 메서드가 반환 된 사용자 지정 마샬러를 사용자 지정 하는 데 사용할 수 있는 쿠키입니다.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);  

MarshalAsAttribute를 적용합니다.Applying MarshalAsAttribute

사용자 지정 마샬러를 사용 하려면 마샬링되는 매개 변수 또는 필드에 MarshalAsAttribute 특성을 적용 해야 합니다.To use a custom marshaler, you must apply the MarshalAsAttribute attribute to the parameter or field that is being marshaled.

또한 UnmanagedType.CustomMarshaler 열거형 값을 MarshalAsAttribute 생성자에 전달 해야 합니다.You must also pass the UnmanagedType.CustomMarshaler enumeration value to the MarshalAsAttribute constructor. 또한 다음과 같은 명명 된 매개 변수 중 하나를 사용 하 여 MarshalType 필드를 지정 해야 합니다.In addition, you must specify the MarshalType field with one of the following named parameters:

  • MarshalType (필수): 사용자 지정 마샬러의 정규화 된 어셈블리 이름입니다.MarshalType (required): The assembly-qualified name of the custom marshaler. 네임 스페이스 및 사용자 지정 마샬러 클래스 이름이 포함 해야 합니다.The name should include the namespace and class of the custom marshaler. 사용자 지정 마샬러는 해당 어셈블리에 정의 되어 있지 않으면, 이전에 정의 된 어셈블리의 이름을 지정 해야 합니다.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.

    참고

    MarshalType 필드 대신 MarshalTypeRef 필드를 사용할 수 있습니다.You can use the MarshalTypeRef field instead of the MarshalType field. MarshalTypeRef 지정 하기 쉬운 형식을 사용 합니다.MarshalTypeRef takes a type that is easier to specify.

  • MarshalCookie (선택 사항): 사용자 지정 마샬러에 전달 되는 쿠키입니다.MarshalCookie (optional): A cookie that is passed to the custom marshaler. 마샬러에 추가 정보를 제공 하는 쿠키를 사용할 수 있습니다.You can use the cookie to provide additional information to the marshaler. 예를 들어 동일한 마샬러 다양 한 래퍼를 제공 하는, 쿠키는 특정 래퍼를 식별 합니다.For example, if the same marshaler is used to provide a number of wrappers, the cookie identifies a specific wrapper. 쿠키는 마샬러의 GetInstance 메서드에 전달 됩니다.The cookie is passed to the GetInstance method of the marshaler.

MarshalAsAttribute 특성은 적절 한 래퍼를 활성화할 수 있도록 사용자 지정 마샬러를 식별 합니다.The MarshalAsAttribute attribute identifies the custom marshaler so it can activate the appropriate wrapper. 공용 언어 런타임의 interop 서비스는 다음 특성을 조사 하 고 사용자 지정 마샬러 첫 번째 시간 마샬링될 인수 (매개 변수 또는 필드) 요구를 만듭니다.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.

그런 다음 런타임은 사용자 지정 마샬러에 대해 MarshalNativeToManagedMarshalManagedToNative 메서드를 호출 하 여 호출을 처리할 올바른 래퍼를 활성화 합니다.The runtime then calls the MarshalNativeToManaged and MarshalManagedToNative methods on the custom marshaler to activate the correct wrapper to handle the call.

사용자 지정 마샬러를 사용 하 여Using a Custom Marshaler

사용자 지정 마샬러에서 완료 되 면 특정 형식에 대 한 사용자 지정 래퍼로 사용할 수 있습니다.When the custom marshaler is complete, you can use it as a custom wrapper for a particular type. 다음 예제에서는 관리 되는 IUserData 인터페이스의 정의를 보여 줍니다.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

다음 예에서 합니다 IUserData 사용 하 여 인터페이스를 NewOldMarshaler 전달할 비관리 클라이언트 애플리케이션을 사용 하도록 설정 하려면 사용자 지정 마샬러는 IOld 인터페이스를 DoSomeStuff 메서드.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 메서드에 대 한 관리 되는 설명은 앞의 예제와 같이 INew 인터페이스를 사용 하지만, 관리 되지 않는 버전의 DoSomeStuff은 다음 예제와 같이 IOld 인터페이스 포인터를 사용 합니다.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);  
}  

IUserData의 관리 되는 정의를 내보내 생성 된 형식 라이브러리는이 예제에 표시 된 관리 되지 않는 정의를 표준 정의 대신 생성 합니다.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. DoSomeStuff 메서드의 관리 되는 정의에서 INew 인수에 적용 되는 MarshalAsAttribute 특성은 다음 예제와 같이 인수가 사용자 지정 마샬러를 사용 함을 나타냅니다.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

앞의 예제에서 MarshalAsAttribute 특성에 제공 되는 첫 번째 매개 변수는 UnmanagedType.CustomMarshaler 열거형 값 UnmanagedType.CustomMarshaler입니다.In the previous examples, the first parameter provided to the MarshalAsAttribute attribute is the UnmanagedType.CustomMarshaler enumeration value UnmanagedType.CustomMarshaler.

두 번째 매개 변수는 사용자 지정 마샬러의 정규화 된 어셈블리 이름을 제공 하는 MarshalType 필드입니다.The second parameter is the MarshalType field, which provides the assembly-qualified name of the custom marshaler. 이 이름은 사용자 지정 마샬러 (MarshalType="MyCompany.NewOldMarshaler")의 네임 스페이스와 클래스로 구성 됩니다.This name consists of the namespace and class of the custom marshaler (MarshalType="MyCompany.NewOldMarshaler").

메서드

CleanUpManagedData(Object)

관리되는 데이터가 필요 없는 경우 이 데이터의 필요한 정리 작업을 수행합니다.Performs necessary cleanup of the managed data when it is no longer needed.

CleanUpNativeData(IntPtr)

관리되지 않는 데이터가 필요 없는 경우 이 데이터의 필요한 정리 작업을 수행합니다.Performs necessary cleanup of the unmanaged data when it is no longer needed.

GetNativeDataSize()

마샬링될 네이티브 데이터의 크기를 반환합니다.Returns the size of the native data to be marshaled.

MarshalManagedToNative(Object)

관리되는 데이터를 관리되지 않는 데이터로 변환합니다.Converts the managed data to unmanaged data.

MarshalNativeToManaged(IntPtr)

관리되지 않는 데이터를 관리되는 데이터로 변환합니다.Converts the unmanaged data to managed data.

적용 대상