パラメーターのマーシャリングをカスタマイズする

.NET ランタイムの既定のパラメーター マーシャリング動作が意図したとおりに動作しない場合は、System.Runtime.InteropServices.MarshalAsAttribute 属性を使用してパラメーターのマーシャリング方法をカスタマイズできます。 これらのカスタマイズ機能は、ランタイム マーシャリングが無効になっている場合は適用されません。

Note

P/InvokeCOM に対するソース生成の相互運用では、パラメーター上の MarshalAsAttribute の小さなサブセットのみが考慮されます。 代わりに、ソース生成の相互運用には MarshalUsingAttribute を使うことをお勧めします。 詳細については、ソース生成のカスタム マーシャリングに関するページを参照してください。

文字列パラメーターのカスタマイズ

.NET には、文字列をマーシャリングするためのさまざまな形式があります。 これらのメソッドは、C スタイルの文字列と Windows 中心の文字列の形式に関する別のセクションに分割されています。

C スタイルの文字列

これらの各形式では、null で終わる文字列をネイティブ コードに渡します。 これらはネイティブ文字列のエンコードが異なります。

System.Runtime.InteropServices.UnmanagedType の値 エンコード
LPStr ANSI
LPUTF8Str UTF-8
LPWStr UTF-16
LPTStr UTF-16

UnmanagedType.VBByRefStr 形式は少し異なります。 LPWStr と同様に、文字列を UTF-16 でエンコードされたネイティブの C スタイルの文字列にマーシャリングします。 ただし、マネージド シグネチャは参照で文字列を渡し、一致するネイティブ シグネチャは値で文字列を受け取ります。 この違いがあるため、StringBuilder を使用しなくても、文字列を値で受け取り、その場で変更するネイティブ API を使用できます。 一致しないネイティブ シグネチャとマネージド シグネチャは混乱しやすいため、手動でこの形式を使用することはお勧めしません。

Windows 中心の文字列形式

COM または OLE インターフェイスとやり取りするときに、ネイティブ関数が文字列を BSTR 引数として受け取ることに気づかれるのではないでしょうか。 UnmanagedType.BStr アンマネージド型を使用して、文字列を BSTR としてマーシャリングすることができます。

WinRT API とやり取りしている場合は、UnmanagedType.HString 形式を使用して文字列を HSTRING としてマーシャリングできます。

配列パラメーターのカスタマイズ

.NET には、配列パラメーターをマーシャリングする方法が複数用意されています。 C スタイルの配列を受け取る API を呼び出す場合は、UnmanagedType.LPArray アンマネージド型を使用します。 配列内の値にカスタマイズされたマーシャリングが必要な場合は、そのために [MarshalAs] 属性に対して ArraySubType フィールドを使用できます。

COM API を使用している場合は、おそらく配列パラメーターを SAFEARRAY* としてマーシャリングする必要があります。 そのためには、UnmanagedType.SafeArray アンマネージド型を使用できます。 SAFEARRAY の要素の既定の種類については、SAFEARRAYの表を参照してください。 MarshalAsAttribute.SafeArraySubType および MarshalAsAttribute.SafeArrayUserDefinedSubType フィールドを使用すると、SAFEARRAY の正確な要素の種類をカスタマイズできます。

ブールまたは 10 進数パラメーターのカスタマイズ

ブールまたは 10 進数パラメーターのマーシャリングについては、「構造体のマーシャリングのカスタマイズ」を参照してください。

オブジェクト パラメーターのカスタマイズ (Windows のみ)

Windows 上の .NET ランタイムには、オブジェクト パラメーターをネイティブ コードにマーシャリングするさまざまな方法が用意されています。

特定の COM インターフェイスとしてのマーシャリング

API が COM オブジェクトへのポインターを受け取る場合、object 型のパラメーターに次の UnmanagedType 形式のいずれかを使用して、以下のような特定のインターフェイスとしてマーシャリングするように .NET に指示できます。

  • IUnknown
  • IDispatch
  • IInspectable

さらに、型が [ComVisible(true)] とマークされている場合、または object 型をマーシャリングする場合は、UnmanagedType.Interface 形式を使用して、オブジェクトをその型の COM ビューの COM 呼び出し可能ラッパーとしてマーシャリングできます。

VARIANT 型へのマーシャリング

ネイティブ API が Win32 VARIANT を受け取る場合、object パラメーターに UnmanagedType.Struct 形式を使用してオブジェクトを VARIANT としてマーシャリングすることができます。 .NET 型と VARIANT 型の間のマッピングについては、object フィールドのカスタマイズに関するドキュメントを参照してください。

カスタム マーシャラー

ネイティブ COM インターフェイスを別のマネージ型にプロジェクションする場合は、UnmanagedType.CustomMarshaler 形式と ICustomMarshaler の実装を使用して独自のカスタム マーシャリング コードを用意できます。