Pengawalan runtime yang dinonaktifkan
Saat atribut System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute
diterapkan ke perakitan, runtime menonaktifkan sebagian besar dukungan bawaan untuk pengawalan data antara representasi terkelola dan asli. Artikel ini menjelaskan fitur yang dinonaktifkan dan bagaimana jenis .NET memetakan ke jenis asli saat pengawalan dinonaktifkan.
Skenario bila pengawalan dinonaktifkan
Ketika DisableRuntimeMarshallingAttribute
diterapkan ke rakitan, itu mempengaruhi jenis P/Invokes dan Delegasi di rakitan, serta panggilan apa pun ke penunjuk fungsi yang tidak terkelola di rakitan. Ini tidak memengaruhi jenis delegasi P/Invoke atau interop yang ditentukan dalam rakitan lain. Ini juga tidak menonaktifkan pengawalan untuk dukungan interop COM bawaan runtime. Dukungan interop COM bawaan dapat diaktifkan atau dinonaktifkan melalui sakelar fitur.
Fitur yang dinonaktifkan
Ketika DisableRuntimeMarshallingAttribute
diterapkan ke rakitan, atribut berikut tidak akan berpengaruh atau melemparkan pengecualian:
- LCIDConversionAttribute pada P/Invoke atau delegasi
SetLastError=true
pada P/InvokeThrowOnUnmappableChar=true
pada P/InvokeBestFitMapping=true
pada P/Invoke- Tanda tangan metode argumen variadik .NET (varargs)
- Parameter
in
,ref
,out
Aturan default untuk pengawalan jenis umum
Ketika pengawalan dinonaktifkan, aturan untuk pengawalan 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 dalam kode terkelola dan asli dan karenanya tidak memerlukan pengawalan apa pun. Selain itu, aturan ini tidak dapat disesuaikan dengan alat yang disebutkan dalam dokumentasi tentang menyesuaikan pengawalan 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 LayoutKind.Auto |
Diperlakukan sebagai jenis blittable. Semua pengawalan struct yang disesuaikan diabaikan. | |
semua jenis lain | tidak didukung |
Contoh
Contoh berikut menunjukkan beberapa fitur yang diaktifkan atau dinonaktifkan saat 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