Using a Substitute Marshaler

Once the marshaler is complete, it can be used as a custom wrapper for a particular type. The following example shows the managed interface definition IUserData:

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

In the following example, the IUserData interface uses the NewOldMarshaler to enable unmanaged clients to pass an IOld interface to the DoSomeStuff method. The managed description of the DoSomeStuff method takes an INew interface, as shown in the previous example, while the unmanaged version of DoSomeStuff takes an IOld interface pointer, as shown in the following example.

Type library representation

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

The type library generated by exporting the managed definition of IUserData yields the unmanaged definition shown in this example rather than the standard definition. 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:

Imports System.Runtime.InteropServices

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

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

When used to specify a custom marshaler, the MarshalAsAttribute takes the following two named parameters:

  • 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 defined in a different assembly from the one it is used in, you must specify the name of the assembly in which it is defined.

    Note

    You can use the MarshalTypeRef field instead of the MarshalType field. MarshalTypeRef takes a type that is easier to specify.

  • MarshalCookie (Optional)

    A cookie passed to the custom marshaler. You can use the cookie to provide additional information to the marshaler. For example, the same marshaler could be used to provide a number of wrappers, for which the cookie identifies the specific wrapper. The cookie is passed to the GetInstance method of the marshaler.

See Also

Concepts

Defining the Marshaling Type

Implementing the ICustomMarshaler Interface

Other Resources

Custom Marshaling