使用替换封送拆收器
更新:2007 年 11 月
当编写完封送拆收器后,可以将其用作特定类型的自定义包装。下面的示例显示了托管接口定义 IUserData:
Public Interface IUserData
Sub DoSomeStuff(pINew As INew)
End Interface
public interface IUserData {
void DoSomeStuff(INew pINew);
}
在下面的示例中,IUserData 接口使用 NewOldMarshaler 使非托管客户端能够将 IOld 接口传递给 DoSomeStuff 方法。DoSomeStuff 方法的托管说明采用 INew 接口(如上例所示),而 DoSomeStuff 的非托管版本采用 IOld 接口指针(如下例所示)。
类型库表示形式
[uuid(9B2BAADA-0705-11D3-A0CD-00C04FA35826)]
library UserLib {
[uuid(9B2BABCD-0705-11D3-A0CD-00C04FA35826)]
interface IUserData : IUnknown
HRESULT DoSomeStuff(IUnknown* pIOld);
}
通过导出 IUserData 托管定义来生成的类型库将生成上例所示的非托管定义,而不是标准的定义。对 DoSomeStuff 方法的托管定义中的 INew 参数应用的 MarshalAsAttribute 属性指示该参数使用了一个自定义的封送拆收器,如下面的示例所示:
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
);
}
当用来指定自定义封送拆收器时,MarshalAsAttribute 将采用以下两个命名参数:
MarshalType(必选项)
自定义封送拆收器的程序集限定名称。此名称应包括自定义封送拆收器的命名空间和类。如果在其中定义自定义封送拆收器的程序集不同于在其中使用它的程序集,则必须指定在其中定义该自定义封送拆收器的程序集的名称。
说明: 可以使用 MarshalTypeRef 字段(而不是 MarshalType 字段)。MarshalTypeRef 采用更易于指定的类型。
MarshalCookie(可选)
传递给自定义封送拆收器的 Cookie。您可以使用该 Cookie 为封送拆收器提供附加信息。例如,可能会使用同一个封送拆收器来提供多个包装,而 Cookie 则标识特定的包装。该 Cookie 将被传递给封送拆收器的 GetInstance 方法。