Marshalling runtime yang dinonaktifkan

Saat atribut System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute diterapkan ke assembly, runtime menonaktifkan sebagian besar dukungan bawaan untuk penyaluran data antara representasi terkelola dan asli. Artikel ini menjelaskan fitur-fitur yang dinonaktifkan dan bagaimana jenis .NET dipetakan ke jenis bawaan ketika marshalling dinonaktifkan.

Skenario di mana marshalling dinonaktifkan

DisableRuntimeMarshallingAttribute Ketika diterapkan ke assembly, ini memengaruhi jenis P/Invokes dan Delegasi di assembly, serta panggilan apa pun ke fungsi pointer yang tidak terkelola di assembly. Ini tidak memengaruhi jenis tipe delegasi P/Invoke atau interop yang ditentukan dalam rakitan lain. Ini juga tidak menonaktifkan marshalling untuk dukungan interop COM bawaan dari runtime. Dukungan interop COM yang sudah terintegrasi dapat diaktifkan atau dinonaktifkan melalui pengalih fitur.

Fitur yang dinonaktifkan

Ketika DisableRuntimeMarshallingAttribute diterapkan ke rakitan, atribut berikut tidak akan berpengaruh atau akan menimbulkan pengecualian:

  • LCIDConversionAttribute pada P/Invoke atau delegat
  • SetLastError=true pada P/Invoke
  • ThrowOnUnmappableChar=true pada P/Invoke
  • BestFitMapping=true pada P/Invoke
  • Tanda tangan metode argumen variadik .NET (varargs)
  • in, ref, out parameter

Aturan default untuk pengaturan data jenis umum

Ketika marshalling dinonaktifkan, aturan untuk marshalling default berubah menjadi aturan yang jauh lebih sederhana. Aturan ini dijelaskan di bawah ini. Seperti disebutkan dalam dokumentasi praktik terbaik interop, jenis blittable adalah jenis dengan tata letak yang sama di dalam kode terkelola dan kode asli dan oleh karena itu tidak memerlukan marshalling apa pun. Selain itu, aturan ini tidak dapat disesuaikan dengan alat yang disebutkan dalam dokumentasi tentang pengolahan parameter.

Kata kunci C# Jenis .NET Jenis Asli
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 pada P/Invoke tidak berpengaruh)
nint System.IntPtr intptr_t
nuint System.UIntPtr uintptr_t
System.Boolean bool
Jenis C# unmanaged yang ditentukan pengguna tanpa bidang dengan LayoutKind.Auto Diperlakukan sebagai jenis yang dapat dibaca mentah tanpa konversi. Semua pengemasan struct yang telah disesuaikan diabaikan.
Semua jenis lainnya tidak didukung

Contoh

Contoh berikut menunjukkan beberapa fitur yang diaktifkan atau tidak berfungsi bila proses marshalling runtime dinonaktifkan. Untuk menunjukkan aplikasi manual panduan ini, contoh ini menggunakan [DllImport] dibandingkan dengan atribut yang direkomendasikan [LibraryImport] . Penganalisis dengan ID SYSLIB1054 memberikan panduan tambahan saat Anda menggunakan [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