次の方法で共有


無効なランタイム マーシャリング

System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute属性がアセンブリに適用されると、ランタイムは、マネージド表現とネイティブ表現の間のデータ マーシャリングに対するほとんどの組み込みサポートを無効にします。 この記事では、無効になっている機能と、マーシャリングを無効にしたときに .NET 型がネイティブ型にマップされる方法について説明します。

マーシャリングが無効になっているシナリオ

DisableRuntimeMarshallingAttributeがアセンブリに適用されると、アセンブリ内の P/Invokes 型とデリゲート型、およびアセンブリ内のアンマネージ関数ポインターの呼び出しに影響します。 他のアセンブリで定義されている P/Invoke または相互運用デリゲート型には影響しません。 また、ランタイムの組み込みの COM 相互運用サポートのマーシャリングも無効になりません。 組み込みの COM 相互運用機能のサポートは、 機能スイッチを使用して有効または無効にすることができます。

無効な機能

DisableRuntimeMarshallingAttributeをアセンブリに適用すると、次の属性は影響を受けたり、例外をスローしたりしません。

  • LCIDConversionAttribute P/Invoke またはデリゲート
  • SetLastError=true P/Invoke の場合
  • ThrowOnUnmappableChar=true P/Invoke の場合
  • BestFitMapping=true P/Invoke の場合
  • .NET 可変引数メソッドシグネチャ (varargs)
  • inrefout パラメーター

共通型のマーシャリングの既定の規則

マーシャリングが無効になっている場合、既定のマーシャリングの規則は、はるかに単純なルールに変更されます。 これらの規則については、以下で説明します。 相互運用のベスト プラクティスのドキュメントで説明したように、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
フィールドのないユーザー定義 の C# unmanagedLayoutKind.Auto 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