オブジェクトに対する既定のマーシャリングDefault Marshaling for Objects

System.Object として型指定されているパラメーターおよびフィールドを、次のいずれかの型としてアンマネージ コードに公開できます。Parameters and fields typed as System.Object can be exposed to unmanaged code as one of the following types:

  • オブジェクトがパラメーターの場合にはバリアント。A variant when the object is a parameter.

  • オブジェクトが構造体フィールドの場合にはインターフェイス。An interface when the object is a structure field.

オブジェクト型のマーシャリングは COM 相互運用機能のみでサポートされます。Only COM interop supports marshaling for object types. 既定の動作では、オブジェクトは COM バリアントにマーシャリングされます。The default behavior is to marshal objects to COM variants. これらの規則は Object 型のみに適用され、Object クラスから派生した、厳密に型指定されたオブジェクトには適用されません。These rules apply only to the type Object and do not apply to strongly typed objects that derive from the Object class.

マーシャリング オプションMarshaling Options

Object データ型のマーシャリング オプションを次の表に示します。The following table shows the marshaling options for the Object data type. MarshalAsAttribute 属性は、オブジェクトをマーシャリングするための UnmanagedType 列挙値をいくつか提供します。The MarshalAsAttribute attribute provides several UnmanagedType enumeration values to marshal objects.

列挙型Enumeration type アンマネージ形式の説明Description of unmanaged format
UnmanagedType.StructUnmanagedType.Struct

(パラメーターの既定値)(default for parameters)
COM スタイルのバリアント。A COM-style variant.
UnmanagedType.InterfaceUnmanagedType.Interface 可能な場合は IDispatch インターフェイス。それ以外の場合は IUnknown インターフェイス。An IDispatch interface, if possible; otherwise, an IUnknown interface.
UnmanagedType.IUnknownUnmanagedType.IUnknown

(フィールドの既定値)(default for fields)
IUnknown インターフェイス。An IUnknown interface.
UnmanagedType.IDispatchUnmanagedType.IDispatch IDispatch インターフェイス。An IDispatch interface.

次の例は、MarshalObject のマネージド インターフェイス定義を示しています。The following example shows the managed interface definition for MarshalObject.

Interface MarshalObject  
   Sub SetVariant(o As Object)  
   Sub SetVariantRef(ByRef o As Object)  
   Function GetVariant() As Object  
  
   Sub SetIDispatch( <MarshalAs(UnmanagedType.IDispatch)> o As Object)  
   Sub SetIDispatchRef(ByRef <MarshalAs(UnmanagedType.IDispatch)> o _  
      As Object)  
   Function GetIDispatch() As <MarshalAs(UnmanagedType.IDispatch)> Object  
   Sub SetIUnknown( <MarshalAs(UnmanagedType.IUnknown)> o As Object)  
   Sub SetIUnknownRef(ByRef <MarshalAs(UnmanagedType.IUnknown)> o _  
      As Object)  
   Function GetIUnknown() As <MarshalAs(UnmanagedType.IUnknown)> Object  
End Interface  
interface MarshalObject {  
   void SetVariant(Object o);  
   void SetVariantRef(ref Object o);  
   Object GetVariant();  
  
   void SetIDispatch ([MarshalAs(UnmanagedType.IDispatch)]Object o);  
   void SetIDispatchRef([MarshalAs(UnmanagedType.IDispatch)]ref Object o);  
   [MarshalAs(UnmanagedType.IDispatch)] Object GetIDispatch();  
   void SetIUnknown ([MarshalAs(UnmanagedType.IUnknown)]Object o);  
   void SetIUnknownRef([MarshalAs(UnmanagedType.IUnknown)]ref Object o);  
   [MarshalAs(UnmanagedType.IUnknown)] Object GetIUnknown();  
}  

次のコードでは、MarshalObject インターフェイスをタイプ ライブラリにエクスポートします。The following code exports the MarshalObject interface to a type library.

interface MarshalObject {  
   HRESULT SetVariant([in] VARIANT o);  
   HRESULT SetVariantRef([in,out] VARIANT *o);  
   HRESULT GetVariant([out,retval] VARIANT *o)   
   HRESULT SetIDispatch([in] IDispatch *o);  
   HRESULT SetIDispatchRef([in,out] IDispatch **o);  
   HRESULT GetIDispatch([out,retval] IDispatch **o)   
   HRESULT SetIUnknown([in] IUnknown *o);  
   HRESULT SetIUnknownRef([in,out] IUnknown **o);  
   HRESULT GetIUnknown([out,retval] IUnknown **o)   
}  

注意

相互運用マーシャラーは、バリアント内に割り当てられたオブジェクトがある場合は、呼び出しの後で自動的にそのオブジェクトを解放します。The interop marshaler automatically frees any allocated object inside the variant after the call.

次の例は、フォーマットされた値型を示しています。The following example shows a formatted value type.

Public Structure ObjectHolder  
   Dim o1 As Object  
   <MarshalAs(UnmanagedType.IDispatch)> Public o2 As Object  
End Structure  
public struct ObjectHolder {  
   Object o1;  
   [MarshalAs(UnmanagedType.IDispatch)]public Object o2;  
}  

次のコードでは、フォーマットされた型をタイプ ライブラリにエクスポートします。The following code exports the formatted type to a type library.

struct ObjectHolder {  
   VARIANT o1;  
   IDispatch *o2;  
}  

インターフェイスへのオブジェクトのマーシャリングMarshaling Object to Interface

オブジェクトがインターフェイスとして COM に公開される場合、そのインターフェイスはマネージド型 Object 用のクラス インターフェイス (_Object インターフェイス) となります。When an object is exposed to COM as an interface, that interface is the class interface for the managed type Object (the _Object interface). このインターフェイスは、結果のタイプ ライブラリでは、IDispatch (UnmanagedType) または IUnknown (UnmanagedType.IUnknown) として型指定されます。This interface is typed as an IDispatch (UnmanagedType) or an IUnknown (UnmanagedType.IUnknown) in the resulting type library. COM クライアントは、マネージド クラスのメンバー、または派生クラスによって実装されるメンバーを _Object インターフェイス経由で動的に呼び出すことができます。COM clients can dynamically invoke the members of the managed class or any members implemented by its derived classes through the _Object interface. クライアントは QueryInterface を呼び出して、マネージド型によって明示的に実装された他の任意のインターフェイスを取得することもできます。The client can also call QueryInterface to obtain any other interface explicitly implemented by the managed type.

バリアントへのオブジェクトのマーシャリングMarshaling Object to Variant

オブジェクトがバリアントにマーシャリングされる場合、内部バリアント型は次の規則に従って実行時に決定されます。When an object is marshaled to a variant, the internal variant type is determined at run time, based on the following rules:

  • オブジェクト参照が null (Visual Basic では Nothing) の場合、オブジェクトは VT_EMPTY 型のバリアントにマーシャリングされます。If the object reference is null (Nothing in Visual Basic), the object is marshaled to a variant of type VT_EMPTY.

  • オブジェクトが、次の表にリストされているいずれかの型のインスタンスである場合、結果として生成されるバリアント型は、表に示されている、マーシャラーに組み込まれている規則によって決定されます。If the object is an instance of any type listed in the following table, the resulting variant type is determined by the rules built into the marshaler and shown in the table.

  • マーシャリング動作を明示的に制御する必要があるその他のオブジェクトは、IConvertible インターフェイスを実装できます。Other objects that need to explicitly control the marshaling behavior can implement the IConvertible interface. その場合、バリアント型は IConvertible.GetTypeCode メソッドから返される型コードによって決定されます。In that case, the variant type is determined by the type code returned from the IConvertible.GetTypeCode method. それ以外の場合、オブジェクトは VT_UNKNOWN 型のバリアントとしてマーシャリングされます。Otherwise, the object is marshaled as a variant of type VT_UNKNOWN.

バリアントへのシステム型のマーシャリングMarshaling System Types to Variant

次の表に、マネージド オブジェクト型とそれに対応する COM バリアント型を示します。The following table shows managed object types and their corresponding COM variant types. これらの型は、呼び出されるメソッドのシグネチャが System.Object 型の場合にのみ変換されます。These types are converted only when the signature of the method being called is of type System.Object.

オブジェクトの種類Object type COM バリアント型COM variant type
null オブジェクト参照 (Visual Basic では Nothing)。Null object reference (Nothing in Visual Basic). VT_EMPTYVT_EMPTY
System.DBNull VT_NULLVT_NULL
System.Runtime.InteropServices.ErrorWrapper VT_ERRORVT_ERROR
System.Reflection.Missing VT_ERRORE_PARAMNOTFOUNDVT_ERROR with E_PARAMNOTFOUND
System.Runtime.InteropServices.DispatchWrapper VT_DISPATCHVT_DISPATCH
System.Runtime.InteropServices.UnknownWrapper VT_UNKNOWNVT_UNKNOWN
System.Runtime.InteropServices.CurrencyWrapper VT_CYVT_CY
System.Boolean VT_BOOLVT_BOOL
System.SByte VT_I1VT_I1
System.Byte VT_UI1VT_UI1
System.Int16 VT_I2VT_I2
System.UInt16 VT_UI2VT_UI2
System.Int32 VT_I4VT_I4
System.UInt32 VT_UI4VT_UI4
System.Int64 VT_I8VT_I8
System.UInt64 VT_UI8VT_UI8
System.Single VT_R4VT_R4
System.Double VT_R8VT_R8
System.Decimal VT_DECIMALVT_DECIMAL
System.DateTime VT_DATEVT_DATE
System.String VT_BSTRVT_BSTR
System.IntPtr VT_INTVT_INT
System.UIntPtr VT_UINTVT_UINT
System.Array VT_ARRAYVT_ARRAY

上の例で定義した MarshalObject インターフェイスを使用して、次のコード例ではさまざまな型のバリアントを COM サーバーに渡す方法を示します。Using the MarshalObject interface defined in the previous example, the following code example demonstrates how to pass various types of variants to a COM server.

Dim mo As New MarshalObject()  
mo.SetVariant(Nothing)         ' Marshal as variant of type VT_EMPTY.  
mo.SetVariant(System.DBNull.Value) ' Marshal as variant of type VT_NULL.  
mo.SetVariant(CInt(27))        ' Marshal as variant of type VT_I2.  
mo.SetVariant(CLng(27))        ' Marshal as variant of type VT_I4.  
mo.SetVariant(CSng(27.0))      ' Marshal as variant of type VT_R4.  
mo.SetVariant(CDbl(27.0))      ' Marshal as variant of type VT_R8.  
MarshalObject mo = new MarshalObject();  
mo.SetVariant(null);            // Marshal as variant of type VT_EMPTY.  
mo.SetVariant(System.DBNull.Value); // Marshal as variant of type VT_NULL.  
mo.SetVariant((int)27);          // Marshal as variant of type VT_I2.  
mo.SetVariant((long)27);          // Marshal as variant of type VT_I4.  
mo.SetVariant((single)27.0);   // Marshal as variant of type VT_R4.  
mo.SetVariant((double)27.0);   // Marshal as variant of type VT_R8.  

ErrorWrapperDispatchWrapperUnknownWrapper、および CurrencyWrapper などのラッパー クラスを使用すると、対応するマネージド型を持たない COM 型をマーシャリングできます。COM types that do not have corresponding managed types can be marshaled using wrapper classes such as ErrorWrapper, DispatchWrapper, UnknownWrapper, and CurrencyWrapper. 次のコード例では、これらのラッパーを使用して、さまざまな型のバリアントを COM サーバーに渡す方法を示します。The following code example demonstrates how to use these wrappers to pass various types of variants to a COM server.

Imports System.Runtime.InteropServices  
' Pass inew as a variant of type VT_UNKNOWN interface.  
mo.SetVariant(New UnknownWrapper(inew))  
' Pass inew as a variant of type VT_DISPATCH interface.  
mo.SetVariant(New DispatchWrapper(inew))  
' Pass a value as a variant of type VT_ERROR interface.  
mo.SetVariant(New ErrorWrapper(&H80054002))  
' Pass a value as a variant of type VT_CURRENCY interface.  
mo.SetVariant(New CurrencyWrapper(New Decimal(5.25)))  
using System.Runtime.InteropServices;  
// Pass inew as a variant of type VT_UNKNOWN interface.  
mo.SetVariant(new UnknownWrapper(inew));  
// Pass inew as a variant of type VT_DISPATCH interface.  
mo.SetVariant(new DispatchWrapper(inew));  
// Pass a value as a variant of type VT_ERROR interface.  
mo.SetVariant(new ErrorWrapper(0x80054002));  
// Pass a value as a variant of type VT_CURRENCY interface.  
mo.SetVariant(new CurrencyWrapper(new Decimal(5.25)));  

ラッパー クラスは、System.Runtime.InteropServices 名前空間で定義されます。The wrapper classes are defined in the System.Runtime.InteropServices namespace.

バリアントへの IConvertible インターフェイスのマーシャリングMarshaling the IConvertible Interface to Variant

前のセクションでリストしたもの以外の型は、IConvertible インターフェイスを実装することにより、型のマーシャリング方法を制御できます。Types other than those listed in the previous section can control how they are marshaled by implementing the IConvertible interface. オブジェクトが IConvertible インターフェイスを実装する場合、その COM バリアント型は IConvertible.GetTypeCode メソッドから返された TypeCode 列挙体の値によって実行時に決定されます。If the object implements the IConvertible interface, the COM variant type is determined at run time by the value of the TypeCode enumeration returned from the IConvertible.GetTypeCode method.

次の表に、TypeCode 列挙体に対して有効な値と、それぞれの値に対応する COM バリアント型を示します。The following table shows the possible values for the TypeCode enumeration and the corresponding COM variant type for each value.

TypeCodeTypeCode COM バリアント型COM variant type
TypeCode.EmptyTypeCode.Empty VT_EMPTYVT_EMPTY
TypeCode.ObjectTypeCode.Object VT_UNKNOWNVT_UNKNOWN
TypeCode.DBNullTypeCode.DBNull VT_NULLVT_NULL
TypeCode.BooleanTypeCode.Boolean VT_BOOLVT_BOOL
TypeCode.CharTypeCode.Char VT_UI2VT_UI2
TypeCode.SbyteTypeCode.Sbyte VT_I1VT_I1
TypeCode.ByteTypeCode.Byte VT_UI1VT_UI1
TypeCode.Int16TypeCode.Int16 VT_I2VT_I2
TypeCode.UInt16TypeCode.UInt16 VT_UI2VT_UI2
TypeCode.Int32TypeCode.Int32 VT_I4VT_I4
TypeCode.UInt32TypeCode.UInt32 VT_UI4VT_UI4
TypeCode.Int64TypeCode.Int64 VT_I8VT_I8
TypeCode.UInt64TypeCode.UInt64 VT_UI8VT_UI8
TypeCode.SingleTypeCode.Single VT_R4VT_R4
TypeCode.DoubleTypeCode.Double VT_R8VT_R8
TypeCode.DecimalTypeCode.Decimal VT_DECIMALVT_DECIMAL
TypeCode.DateTimeTypeCode.DateTime VT_DATEVT_DATE
TypeCode.StringTypeCode.String VT_BSTRVT_BSTR
サポートされていません。Not supported. VT_INTVT_INT
サポートされていません。Not supported. VT_UINTVT_UINT
サポートされていません。Not supported. VT_ARRAYVT_ARRAY
サポートされていません。Not supported. VT_RECORDVT_RECORD
サポートされていません。Not supported. VT_CYVT_CY
サポートされていません。Not supported. VT_VARIANTVT_VARIANT

COM バリアントの値は、IConvertible.To Type インターフェイスを呼び出すことによって決定されます。この To Type は、IConvertible.GetTypeCode から返された型に対応する変換ルーチンです。The value of the COM variant is determined by calling the IConvertible.To Type interface, where To Type is the conversion routine that corresponds to the type that was returned from IConvertible.GetTypeCode. たとえば、IConvertible.GetTypeCode から TypeCode.Double を返すオブジェクトは、VT_R8 型の COM バリアントとしてマーシャリングされます。For example, an object that returns TypeCode.Double from IConvertible.GetTypeCode is marshaled as a COM variant of type VT_R8. バリアントの値 (COM バリアントの dblVal フィールド内に格納される) は、IConvertible インターフェイスにキャストし、ToDouble メソッドを呼び出すことで取得できます。You can obtain the value of the variant (stored in the dblVal field of the COM variant) by casting to the IConvertible interface and calling the ToDouble method.

オブジェクトへのバリアントのマーシャリングMarshaling Variant to Object

バリアントをオブジェクトにマーシャリングする場合、マーシャリングされるバリアントの型、および場合によっては値で、生成されるオブジェクトの型が決まります。When marshaling a variant to an object, the type, and sometimes the value, of the marshaled variant determines the type of object produced. 次の表に、各バリアント型とそれに対応するオブジェクト型を示します。オブジェクト型はバリアントが COM から .NET Framework に渡されるときにマーシャラーによって作成されます。The following table identifies each variant type and the corresponding object type that the marshaler creates when a variant is passed from COM to the .NET Framework.

COM バリアント型COM variant type オブジェクトの種類Object type
VT_EMPTYVT_EMPTY null オブジェクト参照 (Visual Basic では Nothing)。Null object reference (Nothing in Visual Basic).
VT_NULLVT_NULL System.DBNull
VT_DISPATCHVT_DISPATCH System.__ComObject、または (pdispVal == null) の場合は nullSystem.__ComObject or null if (pdispVal == null)
VT_UNKNOWNVT_UNKNOWN System.__ComObject、または (punkVal == null) の場合は nullSystem.__ComObject or null if (punkVal == null)
VT_ERRORVT_ERROR System.UInt32
VT_BOOLVT_BOOL System.Boolean
VT_I1VT_I1 System.SByte
VT_UI1VT_UI1 System.Byte
VT_I2VT_I2 System.Int16
VT_UI2VT_UI2 System.UInt16
VT_I4VT_I4 System.Int32
VT_UI4VT_UI4 System.UInt32
VT_I8VT_I8 System.Int64
VT_UI8VT_UI8 System.UInt64
VT_R4VT_R4 System.Single
VT_R8VT_R8 System.Double
VT_DECIMALVT_DECIMAL System.Decimal
VT_DATEVT_DATE System.DateTime
VT_BSTRVT_BSTR System.String
VT_INTVT_INT System.Int32
VT_UINTVT_UINT System.UInt32
VT_ARRAY | VT_*VT_ARRAY | VT_* System.Array
VT_CYVT_CY System.Decimal
VT_RECORDVT_RECORD 対応するボックス化された値型。Corresponding boxed value type.
VT_VARIANTVT_VARIANT サポートされていません。Not supported.

COM からマネージド コードに渡された後で COM に返されるバリアント型が、呼び出し中に同じバリアント型を維持しないことがあります。Variant types passed from COM to managed code and then back to COM might not retain the same variant type for the duration of the call. VT_DISPATCH 型のバリアントが COM から .NET Framework に渡される場合、どのようになるかを考えてみましょう。Consider what happens when a variant of type VT_DISPATCH is passed from COM to the .NET Framework. マーシャリング時に、バリアントは System.Object に変換されます。During marshaling, the variant is converted to a System.Object. その後、Object が COM に返される場合は、VT_UNKNOWN 型のバリアントにマーシャリングされます。If the Object is then passed back to COM, it is marshaled back to a variant of type VT_UNKNOWN. オブジェクトをマネージド コードから COM にマーシャリングするときに、生成されるバリアントの型が、最初にオブジェクトを生成するときに使用したバリアントの型と同じになる保証はありません。There is no guarantee that the variant produced when an object is marshaled from managed code to COM will be the same type as the variant initially used to produce the object.

ByRef バリアントのマーシャリングMarshaling ByRef Variants

バリアント自体を値渡し、または参照渡しすることはできますが、VT_BYREF フラグを任意のバリアント型と併用した場合は、そのバリアントの内容を値渡しではなく、参照渡しすることを指定できます。Although variants themselves can be passed by value or by reference, the VT_BYREF flag can also be used with any variant type to indicate that the contents of the variant are being passed by reference instead of by value. バリアントの参照渡しによるマーシャリングと、VT_BYREF フラグの設定によるバリアントのマーシャリングとの違いがわかりづらい場合がああります。The difference between marshaling variants by reference and marshaling a variant with the VT_BYREF flag set can be confusing. その違いを次の図で明確にします。The following illustration clarifies the differences:

スタックに渡されたバリアントを示す図。
値渡しされるバリアントと参照渡しされるバリアントVariants passed by value and by reference

オブジェクトとバリアントを値渡しでマーシャリングする場合の既定の動作Default behavior for marshaling objects and variants by value

  • オブジェクトをマネージド コードから COM に渡す場合、そのオブジェクトの内容は、「バリアントへのオブジェクトのマーシャリング」で定義されている規則を使用して、マーシャラーによって作成される新しいバリアントにコピーされます。When passing objects from managed code to COM, the contents of the object are copied into a new variant created by the marshaler, using the rules defined in Marshaling Object to Variant. アンマネージ側でバリアントに対して行われた変更の内容は、呼び出しから制御が返されるときに、元のオブジェクトには反映されません。Changes made to the variant on the unmanaged side are not propagated back to the original object on return from the call.

  • バリアントを COM からマネージド コードに渡す場合、そのバリアントの内容は、「オブジェクトへのバリアントのマーシャリング」で定義されている規則を使用して、新規作成されるオブジェクトにコピーされます。When passing variants from COM to managed code, the contents of the variant are copied to a newly created object, using the rules defined in Marshaling Variant to Object. マネージド側でオブジェクトに対して行われた変更の内容は、呼び出しから制御が返されるときに、元のバリアントには反映されません。Changes made to the object on the managed side are not propagated back to the original variant on return from the call.

オブジェクトとバリアントを参照渡しでマーシャリングする場合の既定の動作Default behavior for marshaling objects and variants by reference

変更内容を呼び出し元に反映させるには、パラメーターを参照渡しする必要があります。To propagate changes back to the caller, the parameters must be passed by reference. たとえば、C# でキーワード ref (Visual Basic マネージド コードの場合は ByRef) を使用すると、パラメーターを参照渡しできます。For example, you can use the ref keyword in C# (or ByRef in Visual Basic managed code) to pass parameters by reference. COM の場合、参照パラメーターは variant * などのポインターを使用して渡されます。In COM, reference parameters are passed using a pointer such as a variant *.

  • オブジェクトを COM に参照渡しする場合、マーシャラーは呼び出しを行う前に新しいバリアントを作成し、オブジェクト参照の内容をそのバリアントにコピーします。When passing an object to COM by reference, the marshaler creates a new variant and copies the contents of the object reference into the variant before the call is made. このバリアントはアンマネージ関数に渡されます。ここで、バリアントの内容を自由に変更できます。The variant is passed to the unmanaged function where the user is free to change the contents of the variant. 呼び出しから制御が返されるときに、アンマネージ側でバリアントが変更されている場合には、その内容が元のオブジェクトに反映されます。On return from the call, any changes made to the variant on the unmanaged side are propagated back to the original object. バリアントの型が、呼び出しに渡されたバリアントの型と異なる場合、変更内容は別の型のオブジェクトに反映されます。If the type of the variant differs from the type of the variant passed to the call, then the changes are propagated back to an object of a different type. つまり、呼び出しに渡したオブジェクトの型が、呼び出しから返されるオブジェクトの型と異なることがあります。That is, the type of the object passed into the call can differ from the type of the object returned from the call.

  • バリアントをマネージド コードに参照渡しする場合、マーシャラーは呼び出しを行う前に、新しいオブジェクトを作成し、バリアントの内容をそのオブジェクトにコピーします。When passing a variant to managed code by reference, the marshaler creates a new object and copies the contents of the variant into the object before making the call. オブジェクトへの参照がマネージド関数に渡されます。ここで、オブジェクトを自由に変更できます。A reference to the object is passed to the managed function, where the user is free to change the object. 呼び出しから制御が返されるときに、参照先オブジェクトが変更されている場合には、その内容が元のバリアントに反映されます。On return from the call, any changes made to the referenced object are propagated back to the original variant. オブジェクトの型が、呼び出しに渡されたオブジェクトの型と異なる場合、元のバリアントの型が変更され、値がそのバリアントに反映されます。If the type of the object differs from the type of the object passed in to the call, the type of the original variant is changed and the value is propagated back into the variant. ここでも、呼び出しに渡されたバリアントの型が、呼び出しから返されるバリアントの型と異なることがあります。Again, the type of the variant passed into the call can differ from the type of the variant returned from the call.

VT_BYREF フラグの設定によるバリアントのマーシャリングの既定の動作Default behavior for marshaling a variant with the VT_BYREF flag set

  • マネージド コードに値渡しされるバリアントに VT_BYREF フラグを設定することにより、そのバリアントに値ではなく、参照が含まれることを示すことができます。A variant being passed to managed code by value can have the VT_BYREF flag set to indicate that the variant contains a reference instead of a value. この場合でも、バリアントは値渡しされるため、オブジェクトにマーシャリングされます。In this case, the variant is still marshaled to an object because the variant is being passed by value. 呼び出しを行う前に、マーシャラーは自動的にバリアントの内容を逆参照し、その内容を新しく作成されるオブジェクトにコピーします。The marshaler automatically dereferences the contents of the variant and copies it into a newly created object before making the call. その後、オブジェクトはマネージド関数に渡されます。ただし、呼び出しから制御が返されるときに、このオブジェクトは元のバリアントには反映されません。The object is then passed into the managed function; however, on return from the call, the object is not propagated back into the original variant. マネージド オブジェクトに対する変更内容は失われます。Changes made to the managed object are lost.

    注意事項

    バリアントに VT_BYREF フラグが設定されていても、値渡しされるバリアントの値を変更する方法はありません。There is no way to change the value of a variant passed by value, even if the variant has the VT_BYREF flag set.

  • マネージド コードに参照渡しされるバリアントについても、VT_BYREF フラグを設定することで、バリアントに別の参照が含まれることを示すことができます。A variant being passed to managed code by reference can also have the VT_BYREF flag set to indicate that the variant contains another reference. このようにすると、バリアントは参照渡しされるため、ref オブジェクトにマーシャリングされます。If it does, the variant is marshaled to a ref object because the variant is being passed by reference. 呼び出しを行う前に、マーシャラーは自動的にバリアントの内容を逆参照し、その内容を新しく作成されるオブジェクトにコピーします。The marshaler automatically dereferences the contents of the variant and copies it into a newly created object before making the call. 呼び出しから制御が返されるときに、オブジェクトの値が元のバリアント内の参照に反映されるのは、そのオブジェクトの型が渡されたオブジェクトの型と同じ場合に限られます。On return from the call, the value of the object is propagated back to the reference within the original variant only if the object is the same type as the object passed in. つまり、VT_BYREF フラグが設定されたバリアントの型が反映によって変更されることはありません。That is, propagation does not change the type of a variant with the VT_BYREF flag set. 呼び出しの間にオブジェクトの型が変更された場合、呼び出しから制御が返されるときに InvalidCastException が発生します。If the type of the object is changed during the call, an InvalidCastException occurs on return from the call.

バリアントとオブジェクトに関する反映規則を次の表にまとめます。The following table summarizes the propagation rules for variants and objects.

FromFrom 終了To 変更内容の反映Changes propagated back
Variant vVariant v Object oObject o NeverNever
Object oObject o Variant vVariant v NeverNever
Variant * pvVariant * pv Ref Object oRef Object o AlwaysAlways
Ref object oRef object o Variant * pvVariant * pv AlwaysAlways
Variant v (VT_BYREF | VT_*)Variant v (VT_BYREF | VT_*) Object oObject o NeverNever
Variant v (VT_BYREF | VT_)Variant v (VT_BYREF | VT_) Ref Object oRef Object o 型が変更されていない場合のみ。Only if the type has not changed.

関連項目See also