パラメーターのマーシャリングをカスタマイズする
.NET ランタイムの既定のパラメーター マーシャリング動作が意図したとおりに動作しない場合は、System.Runtime.InteropServices.MarshalAsAttribute 属性を使用してパラメーターのマーシャリング方法をカスタマイズできます。 これらのカスタマイズ機能は、ランタイム マーシャリングが無効になっている場合は適用されません。
Note
P/Invoke と COM に対するソース生成の相互運用では、パラメーター上の 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 の実装を使用して独自のカスタム マーシャリング コードを用意できます。
.NET