특성이 System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute
어셈블리에 적용되면 런타임은 관리되는 표현과 네이티브 표현 간의 데이터 마샬링에 대한 대부분의 기본 제공 지원을 사용하지 않도록 설정합니다. 이 문서에서는 비활성화된 기능과 마샬링을 사용하지 않도록 설정할 때 .NET 형식이 네이티브 형식에 매핑되는 방법을 설명합니다.
마샬링을 사용할 수 없는 시나리오
어셈블리에 DisableRuntimeMarshallingAttribute
가 적용되면, 어셈블리 내 P/Invokes 및 대리자 형식뿐만 아니라, 관리되지 않는 함수 포인터에 대한 모든 호출에도 영향을 미칩니다. 다른 어셈블리에 정의된 P/Invoke 또는 interop 대리자 형식에는 영향을 주지 않습니다. 또한 런타임의 기본 제공 COM 인터롭 지원에 대해 마샬링 비활성화를 설정하지 않습니다.
기능 스위치를 통해 기본 제공 COM interop 지원을 사용하거나 사용하지 않도록 설정할 수 있습니다.
사용 안 함 기능
어셈블리에 DisableRuntimeMarshallingAttribute
가 적용된 경우, 다음 특성은 효과가 없거나 예외를 발생시킵니다.
- LCIDConversionAttribute P/Invoke 또는 대리자
-
SetLastError=true
P/Invoke를 사용하여 -
ThrowOnUnmappableChar=true
P/Invoke를 사용하여 -
BestFitMapping=true
P/Invoke를 사용하여 - .NET 가변 인수 메서드 시그니처(varargs)
-
in
매개변수,ref
매개변수,out
매개변수.
일반 형식 마샬링에 대한 기본 규칙
마샬링을 사용하지 않도록 설정하면 기본 마샬링 규칙이 훨씬 더 간단한 규칙으로 변경됩니다. 이러한 규칙은 아래에 설명되어 있습니다. interop 모범 사례 설명서에서 설명한 것처럼 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 (CharSet P/Invoke에서는 효과가 없음) |
nint |
System.IntPtr |
intptr_t |
nuint |
System.UIntPtr |
uintptr_t |
System.Boolean |
bool |
|
필드가 없는 사용자 정의 C# unmanaged 형식 LayoutKind.Auto |
Blittable 형식으로 처리됩니다. 사용자 지정된 모든 구조체 마샬링이 무시됩니다. | |
기타 모든 형식 | 지원 되지 않는 |
예시
다음 예제에서는 런타임 마샬링을 사용하지 않도록 설정할 때 사용하거나 사용하지 않도록 설정된 몇 가지 기능을 보여 줍니다. 이 지침의 수동 적용을 보여주기 위해, 이 예제는 권장되는 [DllImport]
속성 대신에 [LibraryImport]
속성을 사용합니다. 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