사용하지 않도록 설정된 런타임 마샬링

System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute 특성이 어셈블리에 적용되면 런타임은 관리 표현과 네이티브 표현 간의 데이터 마샬링에 대한 대부분의 네이티브 제공 지원을 사용하지 않도록 설정합니다. 이 문서에서는 사용하지 않도록 설정된 기능과 마샬링이 사용하지 않도록 설정되었을 때 .NET 형식이 네이티브 형식에 매핑되는 방법을 설명합니다.

마샬링이 사용하지 않도록 설정된 시나리오

DisableRuntimeMarshallingAttribute가 어셈블리에 적용되면 어셈블리의 P/Invokes 및 Delegate 형식은 물론 어셈블리의 관리되지 않는 함수 포인터에 대한 모든 호출에도 영향을 미칩니다. 다른 어셈블리에 정의된 P/Invoke 또는 interop 대리자 형식에는 영향을 주지 않습니다. 또한 런타임의 기본 제공 COM interop 지원에 대한 마샬링을 사용하도록 설정합니다. 기본 제공된 COM interop 지원은 기능 스위치를 통해 사용하거나 사용하지 않도록 설정할 수 있습니다.

사용할 수 없는 기능

DisableRuntimeMarshallingAttribute가 어셈블리에 적용되면 다음 특성은 효과가 없거나 예외가 throw됩니다.

  • P/Invoke 또는 대리자의 LCIDConversionAttribute
  • P/Invoke의 SetLastError=true
  • P/Invoke의 ThrowOnUnmappableChar=true
  • P/Invoke의 BestFitMapping=true
  • .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