無効なランタイム マーシャリング
System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute
属性がアセンブリに適用されると、マネージド表現とネイティブ表現の間のデータ マーシャリングに関するほとんどの組み込みサポートが、ランタイムによって無効にされます。 この記事では、マーシャリングが無効にされたときに、無効になる機能と、.NET 型のネイティブ型へのマップ方法について説明します。
マーシャリングが無効にされるシナリオ
DisableRuntimeMarshallingAttribute
がアセンブリに適用されると、アセンブリ内の P/invoke および Delegate 型と、アセンブリ内でのアンマネージド関数ポインターの呼び出しに、影響があります。 他のアセンブリで定義されている P/Invoke または相互運用デリゲート型には影響しません。 また、ランタイムの組み込み COM 相互運用サポートに関するマーシャリングが無効になることもありません。 組み込み COM 相互運用のサポートは、機能スイッチを使って有効または無効にすることができます。
無効になる機能
DisableRuntimeMarshallingAttribute
がアセンブリに適用されると、次の属性は効果がなくなるか、例外をスローします。
- LCIDConversionAttribute (P/Invoke またはデリゲート)
SetLastError=true
(P/Invoke)ThrowOnUnmappableChar=true
(P/Invoke)BestFitMapping=true
(P/Invoke)- .NET の可変個引数のメソッドのシグネチャ (varargs)
in
、ref
、out
パラメーター
共通型をマーシャリングする場合の既定の規則
マーシャリングが無効になると、既定のマーシャリングの規則は、はるかに単純な規則に変わります。 これらの規則について以下で説明します。 相互運用のベスト プラクティスに関するドキュメントで説明されているように、blittable 型はマネージド コードとネイティブ コードでレイアウトが同じ型であるため、マーシャリングを必要としません。 また、これらの規則は、パラメーターのマーシャリングのカスタマイズに関するドキュメントで説明されているツールを使ってカスタマイズすることはできません。
C# キーワード | .NET 型 | ネイティブ型 |
---|---|---|
byte |
System.Byte |
uint8_t |
sbyte |
System.SByte |
int8_t |
short |
System.Int16 |
int16_t |
ushort |
System.UInt16 |
uint16_t |
int |
System.Int32 |
int32_t |
uint |
System.UInt32 |
uint32_t |
long |
System.Int64 |
int64_t |
ulong |
System.UInt64 |
uint64_t |
char |
System.Char |
char16_t (P/Invoke の CharSet には影響ありません) |
nint |
System.IntPtr |
intptr_t |
nuint |
System.UIntPtr |
uintptr_t |
System.Boolean |
bool |
|
LayoutKind.Auto であるフィールドがないユーザー定義の C# unmanaged 型 |
blittable 型として扱われます。 カスタマイズされた構造体のマーシャリングはすべて無視されます。 | |
その他のすべての型 | サポートされていない |
例
次の例では、ランタイム マーシャリングが無効になると有効または無効にされるいくつかの機能を示します。 このガイダンスの手動適用を実証するために、これらの例では推奨される [LibraryImport]
属性ではなく [DllImport]
属性を使用します。 ID が SYSLIB1054 のアナライザーでは、[LibraryImport]
を使用する際に追加のガイダンスが提供されます。
using System.Runtime.InteropServices;
struct Unmanaged
{
int i;
}
[StructLayout(LayoutKind.Auto)]
struct AutoLayout
{
int i;
}
struct StructWithAutoLayoutField
{
AutoLayout f;
}
[UnmanagedFunctionPointer] // OK: UnmanagedFunctionPointer attribute is supported
public delegate void Callback();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] // OK: Specifying a calling convention is supported
public delegate void Callback2(int i); // OK: primitive value types are allowed
[DllImport("NativeLibrary", EntryPoint = "CustomEntryPointName")] // OK: Specifying a custom entry-point name is supported
public static extern void Import(int i);
[DllImport("NativeLibrary", CallingConvention = CallingConvention.Cdecl)] // OK: Specifying a custom calling convention is supported
public static extern void Import(int i);
[UnmanagedCallConv(new[] { typeof(CallConvCdecl) })] // OK: Specifying a custom calling convention is supported
[DllImport("NativeLibrary")]
public static extern void Import(int i);
[DllImport("NativeLibrary", EntryPoint = "CustomEntryPointName", CharSet = CharSet.Unicode, ExactSpelling = false)] // OK: Specifying a custom entry-point name and using CharSet-based lookup is supported
public static extern void Import(int i);
[DllImport("NativeLibrary")] // OK: Not explicitly specifying an entry-point name is supported
public static extern void Import(Unmanaged u); // OK: unmanaged type
[DllImport("NativeLibrary")] // OK: Not explicitly specifying an entry-point name is supported
public static extern void Import(StructWithAutoLayoutField u); // Error: unmanaged type with auto-layout field
[DllImport("NativeLibrary")]
public static extern void Import(Callback callback); // Error: managed types are not supported when runtime marshalling is disabled
.NET