3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 namespace System
.StubHelpers
{
10 using Microsoft
.Win32
;
11 using System
.Security
;
12 using System
.Collections
.Generic
;
14 using System
.Runtime
.InteropServices
;
15 #if FEATURE_COMINTEROP
16 using System
.Runtime
.InteropServices
.WindowsRuntime
;
17 #endif // FEATURE_COMINTEROP
18 using System
.Runtime
.CompilerServices
;
19 using System
.Runtime
.ConstrainedExecution
;
20 using System
.Diagnostics
.Contracts
;
22 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
23 internal static class AnsiCharMarshaler
25 // The length of the returned array is an approximation based on the length of the input string and the system
26 // character set. It is only guaranteed to be larger or equal to cbLength, don't depend on the exact value.
27 [System
.Security
.SecurityCritical
]
28 unsafe static internal byte[] DoAnsiConversion(string str
, bool fBestFit
, bool fThrowOnUnmappableChar
, out int cbLength
)
30 byte[] buffer
= new byte[(str
.Length
+ 1) * Marshal
.SystemMaxDBCSCharSize
];
31 fixed (byte *bufferPtr
= buffer
)
33 cbLength
= str
.ConvertToAnsi(bufferPtr
, buffer
.Length
, fBestFit
, fThrowOnUnmappableChar
);
38 [System
.Security
.SecurityCritical
]
39 unsafe static internal byte ConvertToNative(char managedChar
, bool fBestFit
, bool fThrowOnUnmappableChar
)
41 int cbAllocLength
= (1 + 1) * Marshal
.SystemMaxDBCSCharSize
;
42 byte* bufferPtr
= stackalloc byte[cbAllocLength
];
44 int cbLength
= managedChar
.ToString().ConvertToAnsi(bufferPtr
, cbAllocLength
, fBestFit
, fThrowOnUnmappableChar
);
46 BCLDebug
.Assert(cbLength
> 0, "Zero bytes returned from DoAnsiConversion in AnsiCharMarshaler.ConvertToNative");
50 static internal char ConvertToManaged(byte nativeChar
)
52 byte[] bytes
= new byte[1] { nativeChar }
;
53 string str
= Encoding
.Default
.GetString(bytes
);
56 } // class AnsiCharMarshaler
58 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
59 internal static class CSTRMarshaler
61 [System
.Security
.SecurityCritical
] // auto-generated
62 static internal unsafe IntPtr
ConvertToNative(int flags
, string strManaged
, IntPtr pNativeBuffer
)
64 if (null == strManaged
)
69 StubHelpers
.CheckStringLength(strManaged
.Length
);
72 byte *pbNativeBuffer
= (byte *)pNativeBuffer
;
74 if (pbNativeBuffer
!= null || Marshal
.SystemMaxDBCSCharSize
== 1)
76 // If we are marshaling into a stack buffer or we can accurately estimate the size of the required heap
77 // space, we will use a "1-pass" mode where we convert the string directly into the unmanaged buffer.
79 // + 1 for the null character from the user
80 nb
= (strManaged
.Length
+ 1) * Marshal
.SystemMaxDBCSCharSize
;
82 // Use the pre-allocated buffer (allocated by localloc IL instruction) if not NULL,
83 // otherwise fallback to AllocCoTaskMem
84 if (pbNativeBuffer
== null)
86 // + 1 for the null character we put in
87 pbNativeBuffer
= (byte*)Marshal
.AllocCoTaskMem(nb
+ 1);
90 nb
= strManaged
.ConvertToAnsi(pbNativeBuffer
, nb
+ 1, 0 != (flags
& 0xFF), 0 != (flags
>> 8));
94 // Otherwise we use a slower "2-pass" mode where we first marshal the string into an intermediate buffer
95 // (managed byte array) and then allocate exactly the right amount of unmanaged memory. This is to avoid
96 // wasting memory on systems with multibyte character sets where the buffer we end up with is often much
97 // smaller than the upper bound for the given managed string.
99 byte[] bytes
= AnsiCharMarshaler
.DoAnsiConversion(strManaged
, 0 != (flags
& 0xFF), 0 != (flags
>> 8), out nb
);
101 // + 1 for the null character from the user. + 1 for the null character we put in.
102 pbNativeBuffer
= (byte*)Marshal
.AllocCoTaskMem(nb
+ 2);
104 Buffer
.Memcpy(pbNativeBuffer
, 0, bytes
, 0, nb
);
107 pbNativeBuffer
[nb
] = 0x00;
108 pbNativeBuffer
[nb
+ 1] = 0x00;
110 return (IntPtr
)pbNativeBuffer
;
113 [System
.Security
.SecurityCritical
] // auto-generated
114 static internal unsafe string ConvertToManaged(IntPtr cstr
)
116 if (IntPtr
.Zero
== cstr
)
119 return new String((sbyte*)cstr
);
122 [System
.Security
.SecurityCritical
] // auto-generated
123 static internal void ClearNative(IntPtr pNative
)
125 Win32Native
.CoTaskMemFree(pNative
);
127 } // class CSTRMarshaler
129 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
130 internal static class UTF8Marshaler
132 const int MAX_UTF8_CHAR_SIZE
= 3;
133 [System
.Security
.SecurityCritical
]
134 static internal unsafe IntPtr
ConvertToNative(int flags
, string strManaged
, IntPtr pNativeBuffer
)
136 if (null == strManaged
)
140 StubHelpers
.CheckStringLength(strManaged
.Length
);
143 byte* pbNativeBuffer
= (byte*)pNativeBuffer
;
145 // If we are marshaling into a stack buffer allocated by the ILStub
146 // we will use a "1-pass" mode where we convert the string directly into the unmanaged buffer.
147 // else we will allocate the precise native heap memory.
148 if (pbNativeBuffer
!= null)
150 // this is the number of bytes allocated by the ILStub.
151 nb
= (strManaged
.Length
+ 1) * MAX_UTF8_CHAR_SIZE
;
153 // nb is the actual number of bytes written by Encoding.GetBytes.
154 // use nb to de-limit the string since we are allocating more than
156 nb
= strManaged
.GetBytesFromEncoding(pbNativeBuffer
, nb
, Encoding
.UTF8
);
158 // required bytes > 260 , allocate required bytes on heap
161 nb
= Encoding
.UTF8
.GetByteCount(strManaged
);
162 // + 1 for the null character.
163 pbNativeBuffer
= (byte*)Marshal
.AllocCoTaskMem(nb
+ 1);
164 strManaged
.GetBytesFromEncoding(pbNativeBuffer
, nb
, Encoding
.UTF8
);
166 pbNativeBuffer
[nb
] = 0x0;
167 return (IntPtr
)pbNativeBuffer
;
170 [System
.Security
.SecurityCritical
]
171 static internal unsafe string ConvertToManaged(IntPtr cstr
)
173 if (IntPtr
.Zero
== cstr
)
175 int nbBytes
= StubHelpers
.strlen((sbyte*)cstr
);
176 return String
.CreateStringFromEncoding((byte*)cstr
, nbBytes
, Encoding
.UTF8
);
179 [System
.Security
.SecurityCritical
]
180 static internal void ClearNative(IntPtr pNative
)
182 if (pNative
!= IntPtr
.Zero
)
184 Win32Native
.CoTaskMemFree(pNative
);
189 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
190 internal static class UTF8BufferMarshaler
192 [System
.Security
.SecurityCritical
]
193 static internal unsafe IntPtr
ConvertToNative(StringBuilder sb
, IntPtr pNativeBuffer
, int flags
)
200 // Convert to string first
201 string strManaged
= sb
.ToString();
204 int nb
= Encoding
.UTF8
.GetByteCount(strManaged
);
206 // EmitConvertSpaceCLRToNative allocates memory
207 byte* pbNativeBuffer
= (byte*)pNativeBuffer
;
208 nb
= strManaged
.GetBytesFromEncoding(pbNativeBuffer
, nb
, Encoding
.UTF8
);
210 pbNativeBuffer
[nb
] = 0x0;
211 return (IntPtr
)pbNativeBuffer
;
214 [System
.Security
.SecurityCritical
]
215 static internal unsafe void ConvertToManaged(StringBuilder sb
, IntPtr pNative
)
220 int nbBytes
= StubHelpers
.strlen((sbyte*)pNative
);
221 int numChar
= Encoding
.UTF8
.GetCharCount((byte*)pNative
, nbBytes
);
223 // +1 GetCharCount return 0 if the pNative points to a
224 // an empty buffer.We still need to allocate an empty
225 // buffer with a '\0' to distingiush it from null.
226 // Note that pinning on (char *pinned = new char[0])
227 // return null and Encoding.UTF8.GetChars do not like
229 char[] cCharBuffer
= new char[numChar
+ 1];
230 cCharBuffer
[numChar
] = '\0';
231 fixed (char* pBuffer
= cCharBuffer
)
233 numChar
= Encoding
.UTF8
.GetChars((byte*)pNative
, nbBytes
, pBuffer
, numChar
);
234 // replace string builder internal buffer
235 sb
.ReplaceBufferInternal(pBuffer
, numChar
);
240 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
241 internal static class BSTRMarshaler
243 [System
.Security
.SecurityCritical
] // auto-generated
244 static internal unsafe IntPtr
ConvertToNative(string strManaged
, IntPtr pNativeBuffer
)
246 if (null == strManaged
)
252 StubHelpers
.CheckStringLength(strManaged
.Length
);
255 bool hasTrailByte
= strManaged
.TryGetTrailByte(out trailByte
);
257 uint lengthInBytes
= (uint)strManaged
.Length
* 2;
261 // this is an odd-sized string with a trailing byte stored in its sync block
265 byte *ptrToFirstChar
;
267 if (pNativeBuffer
!= IntPtr
.Zero
)
269 // If caller provided a buffer, construct the BSTR manually. The size
270 // of the buffer must be at least (lengthInBytes + 6) bytes.
272 uint length
= *((uint *)pNativeBuffer
.ToPointer());
273 BCLDebug
.Assert(length
>= lengthInBytes
+ 6, "BSTR localloc'ed buffer is too small");
277 *((uint *)pNativeBuffer
.ToPointer()) = lengthInBytes
;
279 ptrToFirstChar
= (byte *)pNativeBuffer
.ToPointer() + 4;
283 // If not provided, allocate the buffer using SysAllocStringByteLen so
284 // that odd-sized strings will be handled as well.
285 ptrToFirstChar
= (byte *)Win32Native
.SysAllocStringByteLen(null, lengthInBytes
).ToPointer();
288 // copy characters from the managed string
289 fixed (char* ch
= strManaged
)
294 (strManaged
.Length
+ 1) * 2);
297 // copy the trail byte if present
300 ptrToFirstChar
[lengthInBytes
- 1] = trailByte
;
303 // return ptr to first character
304 return (IntPtr
)ptrToFirstChar
;
308 [System
.Security
.SecurityCritical
] // auto-generated
309 static internal unsafe string ConvertToManaged(IntPtr bstr
)
311 if (IntPtr
.Zero
== bstr
)
317 uint length
= Win32Native
.SysStringByteLen(bstr
);
319 // Intentionally checking the number of bytes not characters to match the behavior
320 // of ML marshalers. This prevents roundtripping of very large strings as the check
321 // in the managed->native direction is done on String length but considering that
322 // it's completely moot on 32-bit and not expected to be important on 64-bit either,
323 // the ability to catch random garbage in the BSTR's length field outweighs this
324 // restriction. If an ordinary null-terminated string is passed instead of a BSTR,
325 // chances are that the length field - possibly being unallocated memory - contains
326 // a heap fill pattern that will have the highest bit set, caught by the check.
327 StubHelpers
.CheckStringLength(length
);
332 // In the empty string case, we need to use FastAllocateString rather than the
333 // String .ctor, since newing up a 0 sized string will always return String.Emtpy.
334 // When we marshal that out as a bstr, it can wind up getting modified which
335 // corrupts String.Empty.
336 ret
= String
.FastAllocateString(0);
340 ret
= new String((char*)bstr
, 0, (int)(length
/ 2));
343 if ((length
& 1) == 1)
345 // odd-sized strings need to have the trailing byte saved in their sync block
346 ret
.SetTrailByte(((byte *)bstr
.ToPointer())[length
- 1]);
353 [System
.Security
.SecurityCritical
] // auto-generated
354 static internal void ClearNative(IntPtr pNative
)
356 if (IntPtr
.Zero
!= pNative
)
358 Win32Native
.SysFreeString(pNative
);
361 } // class BSTRMarshaler
363 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
364 internal static class VBByValStrMarshaler
366 [System
.Security
.SecurityCritical
] // auto-generated
367 static internal unsafe IntPtr
ConvertToNative(string strManaged
, bool fBestFit
, bool fThrowOnUnmappableChar
, ref int cch
)
369 if (null == strManaged
)
376 cch
= strManaged
.Length
;
378 StubHelpers
.CheckStringLength(cch
);
380 // length field at negative offset + (# of characters incl. the terminator) * max ANSI char size
381 int nbytes
= sizeof(uint) + ((cch
+ 1) * Marshal
.SystemMaxDBCSCharSize
);
383 pNative
= (byte*)Marshal
.AllocCoTaskMem(nbytes
);
384 int* pLength
= (int*)pNative
;
386 pNative
= pNative
+ sizeof(uint);
396 byte[] bytes
= AnsiCharMarshaler
.DoAnsiConversion(strManaged
, fBestFit
, fThrowOnUnmappableChar
, out nbytesused
);
398 BCLDebug
.Assert(nbytesused
< nbytes
, "Insufficient buffer allocated in VBByValStrMarshaler.ConvertToNative");
399 Buffer
.Memcpy(pNative
, 0, bytes
, 0, nbytesused
);
401 pNative
[nbytesused
] = 0;
402 *pLength
= nbytesused
;
405 return new IntPtr(pNative
);
408 [System
.Security
.SecurityCritical
] // auto-generated
409 static internal unsafe string ConvertToManaged(IntPtr pNative
, int cch
)
411 if (IntPtr
.Zero
== pNative
)
416 return new String((sbyte*)pNative
, 0, cch
);
419 [System
.Security
.SecurityCritical
] // auto-generated
420 static internal unsafe void ClearNative(IntPtr pNative
)
422 if (IntPtr
.Zero
!= pNative
)
424 Win32Native
.CoTaskMemFree((IntPtr
)(((long)pNative
) - sizeof(uint)));
427 } // class VBByValStrMarshaler
429 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
430 internal static class AnsiBSTRMarshaler
432 [System
.Security
.SecurityCritical
] // auto-generated
433 static internal unsafe IntPtr
ConvertToNative(int flags
, string strManaged
)
435 if (null == strManaged
)
440 int length
= strManaged
.Length
;
442 StubHelpers
.CheckStringLength(length
);
449 bytes
= AnsiCharMarshaler
.DoAnsiConversion(strManaged
, 0 != (flags
& 0xFF), 0 != (flags
>> 8), out nb
);
452 return Win32Native
.SysAllocStringByteLen(bytes
, (uint)nb
);
455 [System
.Security
.SecurityCritical
] // auto-generated
456 static internal unsafe string ConvertToManaged(IntPtr bstr
)
458 if (IntPtr
.Zero
== bstr
)
464 // We intentionally ignore the length field of the BSTR for back compat reasons.
465 // Unfortunately VB.NET uses Ansi BSTR marshaling when a string is passed ByRef
466 // and we cannot afford to break this common scenario.
467 return new String((sbyte*)bstr
);
471 [System
.Security
.SecurityCritical
] // auto-generated
472 static internal unsafe void ClearNative(IntPtr pNative
)
474 if (IntPtr
.Zero
!= pNative
)
476 Win32Native
.SysFreeString(pNative
);
479 } // class AnsiBSTRMarshaler
481 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
482 internal static class WSTRBufferMarshaler
484 static internal IntPtr
ConvertToNative(string strManaged
)
486 Contract
.Assert(false, "NYI");
490 static internal unsafe string ConvertToManaged(IntPtr bstr
)
492 Contract
.Assert(false, "NYI");
496 static internal void ClearNative(IntPtr pNative
)
498 Contract
.Assert(false, "NYI");
500 } // class WSTRBufferMarshaler
503 #if FEATURE_COMINTEROP
506 [StructLayout(LayoutKind
.Sequential
)]
507 internal struct DateTimeNative
509 public Int64 UniversalTime
;
512 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
513 internal static class DateTimeOffsetMarshaler
{
515 // Numer of ticks counted between 0001-01-01, 00:00:00 and 1601-01-01, 00:00:00.
516 // You can get this through: (new DateTimeOffset(1601, 1, 1, 0, 0, 1, TimeSpan.Zero)).Ticks;
517 private const Int64 ManagedUtcTicksAtNativeZero
= 504911232000000000;
520 internal static void ConvertToNative(ref DateTimeOffset managedDTO
, out DateTimeNative dateTime
) {
522 Int64 managedUtcTicks
= managedDTO
.UtcTicks
;
523 dateTime
.UniversalTime
= managedUtcTicks
- ManagedUtcTicksAtNativeZero
;
527 internal static void ConvertToManaged(out DateTimeOffset managedLocalDTO
, ref DateTimeNative nativeTicks
) {
529 Int64 managedUtcTicks
= ManagedUtcTicksAtNativeZero
+ nativeTicks
.UniversalTime
;
530 DateTimeOffset managedUtcDTO
= new DateTimeOffset(managedUtcTicks
, TimeSpan
.Zero
);
532 // Some Utc times cannot be represented in local time in certain timezones. E.g. 0001-01-01 12:00:00 AM cannot
533 // be represented in any timezones with a negative offset from Utc. We throw an ArgumentException in that case.
534 managedLocalDTO
= managedUtcDTO
.ToLocalTime(true);
536 } // class DateTimeOffsetMarshaler
538 #endif // FEATURE_COMINTEROP
541 #if FEATURE_COMINTEROP
542 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
543 internal static class HStringMarshaler
545 // Slow-path, which requires making a copy of the managed string into the resulting HSTRING
547 internal static unsafe IntPtr
ConvertToNative(string managed
)
549 if (!Environment
.IsWinRTSupported
)
550 throw new PlatformNotSupportedException(Environment
.GetResourceString("PlatformNotSupported_WinRT"));
552 throw new ArgumentNullException(); // We don't have enough information to get the argument name just yet - that support will be coming in M3
555 int hrCreate
= System
.Runtime
.InteropServices
.WindowsRuntime
.UnsafeNativeMethods
.WindowsCreateString(managed
, managed
.Length
, &hstring
);
556 Marshal
.ThrowExceptionForHR(hrCreate
, new IntPtr(-1));
560 // Fast-path, which creates a reference over a pinned managed string. This may only be used if the
561 // pinned string and HSTRING_HEADER will outlive the HSTRING produced (for instance, as an in parameter).
563 // Note that the managed string input to this method MUST be pinned, and stay pinned for the lifetime of
564 // the returned HSTRING object. If the string is not pinned, or becomes unpinned before the HSTRING's
565 // lifetime ends, the HSTRING instance will be corrupted.
567 internal static unsafe IntPtr
ConvertToNativeReference(string managed
,
568 [Out
] HSTRING_HEADER
*hstringHeader
)
570 if (!Environment
.IsWinRTSupported
)
571 throw new PlatformNotSupportedException(Environment
.GetResourceString("PlatformNotSupported_WinRT"));
573 throw new ArgumentNullException(); // We don't have enough information to get the argument name just yet - that support will be coming in M3
575 // The string must also be pinned by the caller to ConvertToNativeReference, which also owns
576 // the HSTRING_HEADER.
577 fixed (char *pManaged
= managed
)
580 int hrCreate
= System
.Runtime
.InteropServices
.WindowsRuntime
.UnsafeNativeMethods
.WindowsCreateStringReference(pManaged
, managed
.Length
, hstringHeader
, &hstring
);
581 Marshal
.ThrowExceptionForHR(hrCreate
, new IntPtr(-1));
587 internal static string ConvertToManaged(IntPtr hstring
)
589 if (!Environment
.IsWinRTSupported
)
591 throw new PlatformNotSupportedException(Environment
.GetResourceString("PlatformNotSupported_WinRT"));
594 return WindowsRuntimeMarshal
.HStringToString(hstring
);
598 internal static void ClearNative(IntPtr hstring
)
600 Contract
.Assert(Environment
.IsWinRTSupported
);
602 if (hstring
!= IntPtr
.Zero
)
604 System
.Runtime
.InteropServices
.WindowsRuntime
.UnsafeNativeMethods
.WindowsDeleteString(hstring
);
607 } // class HStringMarshaler
609 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
610 internal static class ObjectMarshaler
612 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
613 static internal extern void ConvertToNative(object objSrc
, IntPtr pDstVariant
);
615 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
616 static internal extern object ConvertToManaged(IntPtr pSrcVariant
);
618 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
619 static internal extern void ClearNative(IntPtr pVariant
);
620 } // class ObjectMarshaler
622 #endif // FEATURE_COMINTEROP
624 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
625 internal static class ValueClassMarshaler
628 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
629 static internal extern void ConvertToNative(IntPtr dst
, IntPtr src
, IntPtr pMT
, ref CleanupWorkList pCleanupWorkList
);
631 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
632 static internal extern void ConvertToManaged(IntPtr dst
, IntPtr src
, IntPtr pMT
);
634 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
635 static internal extern void ClearNative(IntPtr dst
, IntPtr pMT
);
636 } // class ValueClassMarshaler
638 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
639 internal static class DateMarshaler
641 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
642 static internal extern double ConvertToNative(DateTime managedDate
);
644 // The return type is really DateTime but we use long to avoid the pain associated with returning structures.
645 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
646 static internal extern long ConvertToManaged(double nativeDate
);
647 } // class DateMarshaler
649 #if FEATURE_COMINTEROP
650 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
651 [FriendAccessAllowed
]
652 internal static class InterfaceMarshaler
654 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
655 static internal extern IntPtr
ConvertToNative(object objSrc
, IntPtr itfMT
, IntPtr classMT
, int flags
);
657 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
658 static internal extern object ConvertToManaged(IntPtr pUnk
, IntPtr itfMT
, IntPtr classMT
, int flags
);
661 [DllImport(JitHelpers
.QCall
), SuppressUnmanagedCodeSecurity
]
662 static internal extern void ClearNative(IntPtr pUnk
);
664 [FriendAccessAllowed
]
665 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
666 static internal extern object ConvertToManagedWithoutUnboxing(IntPtr pNative
);
667 } // class InterfaceMarshaler
668 #endif // FEATURE_COMINTEROP
670 #if FEATURE_COMINTEROP
671 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
672 internal static class UriMarshaler
674 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
675 static internal extern string GetRawUriFromNative(IntPtr pUri
);
677 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
678 [System
.Security
.SecurityCritical
]
679 static unsafe internal extern IntPtr
CreateNativeUriInstanceHelper(char* rawUri
, int strLen
);
681 [System
.Security
.SecurityCritical
]
682 static unsafe internal IntPtr
CreateNativeUriInstance(string rawUri
)
684 fixed(char* pManaged
= rawUri
)
686 return CreateNativeUriInstanceHelper(pManaged
, rawUri
.Length
);
690 } // class InterfaceMarshaler
692 [FriendAccessAllowed
]
693 internal static class EventArgsMarshaler
696 [FriendAccessAllowed
]
697 static internal IntPtr
CreateNativeNCCEventArgsInstance(int action
, object newItems
, object oldItems
, int newIndex
, int oldIndex
)
699 IntPtr newItemsIP
= IntPtr
.Zero
;
700 IntPtr oldItemsIP
= IntPtr
.Zero
;
702 RuntimeHelpers
.PrepareConstrainedRegions();
705 if (newItems
!= null)
706 newItemsIP
= Marshal
.GetComInterfaceForObject(newItems
, typeof(IBindableVector
));
707 if (oldItems
!= null)
708 oldItemsIP
= Marshal
.GetComInterfaceForObject(oldItems
, typeof(IBindableVector
));
710 return CreateNativeNCCEventArgsInstanceHelper(action
, newItemsIP
, oldItemsIP
, newIndex
, oldIndex
);
714 if (!oldItemsIP
.IsNull())
715 Marshal
.Release(oldItemsIP
);
716 if (!newItemsIP
.IsNull())
717 Marshal
.Release(newItemsIP
);
722 [FriendAccessAllowed
]
723 [DllImport(JitHelpers
.QCall
), SuppressUnmanagedCodeSecurity
]
724 static extern internal IntPtr
CreateNativePCEventArgsInstance([MarshalAs(UnmanagedType
.HString
)]string name
);
727 [DllImport(JitHelpers
.QCall
), SuppressUnmanagedCodeSecurity
]
728 static extern internal IntPtr
CreateNativeNCCEventArgsInstanceHelper(int action
, IntPtr newItem
, IntPtr oldItem
, int newIndex
, int oldIndex
);
730 #endif // FEATURE_COMINTEROP
732 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
733 internal static class MngdNativeArrayMarshaler
735 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
736 static internal extern void CreateMarshaler(IntPtr pMarshalState
, IntPtr pMT
, int dwFlags
);
738 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
739 static internal extern void ConvertSpaceToNative(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
741 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
742 static internal extern void ConvertContentsToNative(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
744 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
745 static internal extern void ConvertSpaceToManaged(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
,
748 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
749 static internal extern void ConvertContentsToManaged(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
751 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
752 static internal extern void ClearNative(IntPtr pMarshalState
, IntPtr pNativeHome
, int cElements
);
754 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
755 static internal extern void ClearNativeContents(IntPtr pMarshalState
, IntPtr pNativeHome
, int cElements
);
756 } // class MngdNativeArrayMarshaler
758 #if FEATURE_COMINTEROP
759 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
760 internal static class MngdSafeArrayMarshaler
762 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
763 static internal extern void CreateMarshaler(IntPtr pMarshalState
, IntPtr pMT
, int iRank
, int dwFlags
);
765 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
766 static internal extern void ConvertSpaceToNative(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
768 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
769 static internal extern void ConvertContentsToNative(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
, object pOriginalManaged
);
771 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
772 static internal extern void ConvertSpaceToManaged(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
774 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
775 static internal extern void ConvertContentsToManaged(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
777 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
778 static internal extern void ClearNative(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
779 } // class MngdSafeArrayMarshaler
781 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
782 internal static class MngdHiddenLengthArrayMarshaler
785 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
786 static internal extern void CreateMarshaler(IntPtr pMarshalState
, IntPtr pMT
, IntPtr cbElementSize
, ushort vt
);
789 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
790 internal static extern void ConvertSpaceToNative(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
793 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
794 internal static extern void ConvertContentsToNative(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
797 internal static unsafe void ConvertContentsToNative_DateTime(ref DateTimeOffset
[] managedArray
, IntPtr pNativeHome
)
799 if (managedArray
!= null)
801 DateTimeNative
*nativeBuffer
= *(DateTimeNative
**)pNativeHome
;
802 for (int i
= 0; i
< managedArray
.Length
; i
++)
804 DateTimeOffsetMarshaler
.ConvertToNative(ref managedArray
[i
], out nativeBuffer
[i
]);
810 internal static unsafe void ConvertContentsToNative_Type(ref System
.Type
[] managedArray
, IntPtr pNativeHome
)
812 if (managedArray
!= null)
814 TypeNameNative
*nativeBuffer
= *(TypeNameNative
**)pNativeHome
;
815 for (int i
= 0; i
< managedArray
.Length
; i
++)
817 SystemTypeMarshaler
.ConvertToNative(managedArray
[i
], &nativeBuffer
[i
]);
823 internal static unsafe void ConvertContentsToNative_Exception(ref Exception
[] managedArray
, IntPtr pNativeHome
)
825 if (managedArray
!= null)
827 Int32
*nativeBuffer
= *(Int32
**)pNativeHome
;
828 for (int i
= 0; i
< managedArray
.Length
; i
++)
830 nativeBuffer
[i
] = HResultExceptionMarshaler
.ConvertToNative(managedArray
[i
]);
836 internal static unsafe void ConvertContentsToNative_Nullable
<T
>(ref Nullable
<T
>[] managedArray
, IntPtr pNativeHome
)
839 if (managedArray
!= null)
841 IntPtr
*nativeBuffer
= *(IntPtr
**)pNativeHome
;
842 for (int i
= 0; i
< managedArray
.Length
; i
++)
844 nativeBuffer
[i
] = NullableMarshaler
.ConvertToNative
<T
>(ref managedArray
[i
]);
850 internal static unsafe void ConvertContentsToNative_KeyValuePair
<K
, V
>(ref KeyValuePair
<K
, V
>[] managedArray
, IntPtr pNativeHome
)
852 if (managedArray
!= null)
854 IntPtr
*nativeBuffer
= *(IntPtr
**)pNativeHome
;
855 for (int i
= 0; i
< managedArray
.Length
; i
++)
857 nativeBuffer
[i
] = KeyValuePairMarshaler
.ConvertToNative
<K
, V
>(ref managedArray
[i
]);
863 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
864 internal static extern void ConvertSpaceToManaged(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
, int elementCount
);
867 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
868 internal static extern void ConvertContentsToManaged(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
871 internal static unsafe void ConvertContentsToManaged_DateTime(ref DateTimeOffset
[] managedArray
, IntPtr pNativeHome
)
873 if (managedArray
!= null)
875 DateTimeNative
*nativeBuffer
= *(DateTimeNative
**)pNativeHome
;
876 for (int i
= 0; i
< managedArray
.Length
; i
++)
878 DateTimeOffsetMarshaler
.ConvertToManaged(out managedArray
[i
], ref nativeBuffer
[i
]);
884 internal static unsafe void ConvertContentsToManaged_Type(ref System
.Type
[] managedArray
, IntPtr pNativeHome
)
886 if (managedArray
!= null)
888 TypeNameNative
*nativeBuffer
= *(TypeNameNative
**)pNativeHome
;
889 for (int i
= 0; i
< managedArray
.Length
; i
++)
891 SystemTypeMarshaler
.ConvertToManaged(&nativeBuffer
[i
], ref managedArray
[i
]);
897 internal static unsafe void ConvertContentsToManaged_Exception(ref Exception
[] managedArray
, IntPtr pNativeHome
)
899 if (managedArray
!= null)
901 Int32
*nativeBuffer
= *(Int32
**)pNativeHome
;
902 for (int i
= 0; i
< managedArray
.Length
; i
++)
904 managedArray
[i
] = HResultExceptionMarshaler
.ConvertToManaged(nativeBuffer
[i
]);
910 internal static unsafe void ConvertContentsToManaged_Nullable
<T
>(ref Nullable
<T
>[] managedArray
, IntPtr pNativeHome
)
913 if (managedArray
!= null)
915 IntPtr
*nativeBuffer
= *(IntPtr
**)pNativeHome
;
916 for (int i
= 0; i
< managedArray
.Length
; i
++)
918 managedArray
[i
] = NullableMarshaler
.ConvertToManaged
<T
>(nativeBuffer
[i
]);
924 internal static unsafe void ConvertContentsToManaged_KeyValuePair
<K
, V
>(ref KeyValuePair
<K
, V
>[] managedArray
, IntPtr pNativeHome
)
926 if (managedArray
!= null)
928 IntPtr
*nativeBuffer
= *(IntPtr
**)pNativeHome
;
929 for (int i
= 0; i
< managedArray
.Length
; i
++)
931 managedArray
[i
] = KeyValuePairMarshaler
.ConvertToManaged
<K
, V
>(nativeBuffer
[i
]);
937 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
938 internal static extern void ClearNativeContents(IntPtr pMarshalState
, IntPtr pNativeHome
, int cElements
);
941 internal static unsafe void ClearNativeContents_Type(IntPtr pNativeHome
, int cElements
)
943 Contract
.Assert(Environment
.IsWinRTSupported
);
945 TypeNameNative
*pNativeTypeArray
= *(TypeNameNative
**)pNativeHome
;
946 if (pNativeTypeArray
!= null)
948 for (int i
= 0; i
< cElements
; ++i
)
950 SystemTypeMarshaler
.ClearNative(pNativeTypeArray
);
955 } // class MngdHiddenLengthArrayMarshaler
957 #endif // FEATURE_COMINTEROP
959 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
960 internal static class MngdRefCustomMarshaler
962 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
963 static internal extern void CreateMarshaler(IntPtr pMarshalState
, IntPtr pCMHelper
);
965 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
966 static internal extern void ConvertContentsToNative(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
968 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
969 static internal extern void ConvertContentsToManaged(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
971 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
972 static internal extern void ClearNative(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
974 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
975 static internal extern void ClearManaged(IntPtr pMarshalState
, ref object pManagedHome
, IntPtr pNativeHome
);
976 } // class MngdRefCustomMarshaler
978 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
979 [System
.Security
.SecurityCritical
]
980 internal struct AsAnyMarshaler
982 private const ushort VTHACK_ANSICHAR
= 253;
983 private const ushort VTHACK_WINBOOL
= 254;
985 private enum BackPropAction
994 // Pointer to MngdNativeArrayMarshaler, ownership not assumed.
995 private IntPtr pvArrayMarshaler
;
997 // Type of action to perform after the CLR-to-unmanaged call.
998 private BackPropAction backPropAction
;
1000 // The managed layout type for BackPropAction.Layout.
1001 private Type layoutType
;
1003 // Cleanup list to be destroyed when clearing the native view (for layouts with SafeHandles).
1004 private CleanupWorkList cleanupWorkList
;
1006 private static bool IsIn(int dwFlags
) { return ((dwFlags & 0x10000000) != 0); }
1007 private static bool IsOut(int dwFlags
) { return ((dwFlags & 0x20000000) != 0); }
1008 private static bool IsAnsi(int dwFlags
) { return ((dwFlags & 0x00FF0000) != 0); }
1009 private static bool IsThrowOn(int dwFlags
) { return ((dwFlags & 0x0000FF00) != 0); }
1010 private static bool IsBestFit(int dwFlags
) { return ((dwFlags & 0x000000FF) != 0); }
1012 internal AsAnyMarshaler(IntPtr pvArrayMarshaler
)
1014 // we need this in case the value being marshaled turns out to be array
1015 BCLDebug
.Assert(pvArrayMarshaler
!= IntPtr
.Zero
, "pvArrayMarshaler must not be null");
1017 this.pvArrayMarshaler
= pvArrayMarshaler
;
1018 this.backPropAction
= BackPropAction
.None
;
1019 this.layoutType
= null;
1020 this.cleanupWorkList
= null;
1023 #region ConvertToNative helpers
1025 [System
.Security
.SecurityCritical
]
1026 private unsafe IntPtr
ConvertArrayToNative(object pManagedHome
, int dwFlags
)
1028 Type elementType
= pManagedHome
.GetType().GetElementType();
1029 VarEnum vt
= VarEnum
.VT_EMPTY
;
1031 switch (Type
.GetTypeCode(elementType
))
1033 case TypeCode
.SByte
: vt
= VarEnum
.VT_I1
; break;
1034 case TypeCode
.Byte
: vt
= VarEnum
.VT_UI1
; break;
1035 case TypeCode
.Int16
: vt
= VarEnum
.VT_I2
; break;
1036 case TypeCode
.UInt16
: vt
= VarEnum
.VT_UI2
; break;
1037 case TypeCode
.Int32
: vt
= VarEnum
.VT_I4
; break;
1038 case TypeCode
.UInt32
: vt
= VarEnum
.VT_UI4
; break;
1039 case TypeCode
.Int64
: vt
= VarEnum
.VT_I8
; break;
1040 case TypeCode
.UInt64
: vt
= VarEnum
.VT_UI8
; break;
1041 case TypeCode
.Single
: vt
= VarEnum
.VT_R4
; break;
1042 case TypeCode
.Double
: vt
= VarEnum
.VT_R8
; break;
1043 case TypeCode
.Char
: vt
= (IsAnsi(dwFlags
) ? (VarEnum
)VTHACK_ANSICHAR
: VarEnum
.VT_UI2
); break;
1044 case TypeCode
.Boolean
: vt
= (VarEnum
)VTHACK_WINBOOL
; break;
1046 case TypeCode
.Object
:
1048 if (elementType
== typeof(IntPtr
))
1050 vt
= (IntPtr
.Size
== 4 ? VarEnum
.VT_I4
: VarEnum
.VT_I8
);
1052 else if (elementType
== typeof(UIntPtr
))
1054 vt
= (IntPtr
.Size
== 4 ? VarEnum
.VT_UI4
: VarEnum
.VT_UI8
);
1061 throw new ArgumentException(Environment
.GetResourceString("Arg_NDirectBadObject"));
1064 // marshal the object as C-style array (UnmanagedType.LPArray)
1065 int dwArrayMarshalerFlags
= (int)vt
;
1066 if (IsBestFit(dwFlags
)) dwArrayMarshalerFlags
|= (1 << 16);
1067 if (IsThrowOn(dwFlags
)) dwArrayMarshalerFlags
|= (1 << 24);
1069 MngdNativeArrayMarshaler
.CreateMarshaler(
1071 IntPtr
.Zero
, // not needed as we marshal primitive VTs only
1072 dwArrayMarshalerFlags
);
1075 IntPtr pNativeHomeAddr
= new IntPtr(&pNativeHome
);
1077 MngdNativeArrayMarshaler
.ConvertSpaceToNative(
1084 MngdNativeArrayMarshaler
.ConvertContentsToNative(
1091 backPropAction
= BackPropAction
.Array
;
1097 [System
.Security
.SecurityCritical
]
1098 private static IntPtr
ConvertStringToNative(string pManagedHome
, int dwFlags
)
1102 // IsIn, IsOut are ignored for strings - they're always in-only
1103 if (IsAnsi(dwFlags
))
1105 // marshal the object as Ansi string (UnmanagedType.LPStr)
1106 pNativeHome
= CSTRMarshaler
.ConvertToNative(
1107 dwFlags
& 0xFFFF, // (throw on unmappable char << 8 | best fit)
1109 IntPtr
.Zero
); // unmanaged buffer will be allocated
1113 // marshal the object as Unicode string (UnmanagedType.LPWStr)
1114 StubHelpers
.CheckStringLength(pManagedHome
.Length
);
1116 int allocSize
= (pManagedHome
.Length
+ 1) * 2;
1117 pNativeHome
= Marshal
.AllocCoTaskMem(allocSize
);
1119 String
.InternalCopy(pManagedHome
, pNativeHome
, allocSize
);
1125 [System
.Security
.SecurityCritical
]
1126 private unsafe IntPtr
ConvertStringBuilderToNative(StringBuilder pManagedHome
, int dwFlags
)
1130 // P/Invoke can be used to call Win32 apis that don't strictly follow CLR in/out semantics and thus may
1131 // leave garbage in the buffer in circumstances that we can't detect. To prevent us from crashing when
1132 // converting the contents back to managed, put a hidden NULL terminator past the end of the official buffer.
1134 // Unmanaged layout:
1135 // +====================================+
1136 // | Extra hidden NULL |
1137 // +====================================+ \
1139 // | [Converted] NULL-terminated string | |- buffer that the target may change
1141 // +====================================+ / <-- native home
1143 // Note that StringBuilder.Capacity is the number of characters NOT including any terminators.
1145 if (IsAnsi(dwFlags
))
1147 StubHelpers
.CheckStringLength(pManagedHome
.Capacity
);
1149 // marshal the object as Ansi string (UnmanagedType.LPStr)
1150 int allocSize
= (pManagedHome
.Capacity
* Marshal
.SystemMaxDBCSCharSize
) + 4;
1151 pNativeHome
= Marshal
.AllocCoTaskMem(allocSize
);
1153 byte* ptr
= (byte*)pNativeHome
;
1154 *(ptr
+ allocSize
- 3) = 0;
1155 *(ptr
+ allocSize
- 2) = 0;
1156 *(ptr
+ allocSize
- 1) = 0;
1162 byte[] bytes
= AnsiCharMarshaler
.DoAnsiConversion(
1163 pManagedHome
.ToString(),
1175 // null-terminate the native string
1176 *(ptr
+ length
) = 0;
1180 backPropAction
= BackPropAction
.StringBuilderAnsi
;
1185 // marshal the object as Unicode string (UnmanagedType.LPWStr)
1186 int allocSize
= (pManagedHome
.Capacity
* 2) + 4;
1187 pNativeHome
= Marshal
.AllocCoTaskMem(allocSize
);
1189 byte* ptr
= (byte*)pNativeHome
;
1190 *(ptr
+ allocSize
- 1) = 0;
1191 *(ptr
+ allocSize
- 2) = 0;
1195 int length
= pManagedHome
.Length
* 2;
1196 pManagedHome
.InternalCopy(pNativeHome
, length
);
1198 // null-terminate the native string
1199 *(ptr
+ length
+ 0) = 0;
1200 *(ptr
+ length
+ 1) = 0;
1204 backPropAction
= BackPropAction
.StringBuilderUnicode
;
1211 [System
.Security
.SecurityCritical
]
1212 private unsafe IntPtr
ConvertLayoutToNative(object pManagedHome
, int dwFlags
)
1214 // Note that the following call will not throw exception if the type
1215 // of pManagedHome is not marshalable. That's intentional because we
1216 // want to maintain the original behavior where this was indicated
1217 // by TypeLoadException during the actual field marshaling.
1218 int allocSize
= Marshal
.SizeOfHelper(pManagedHome
.GetType(), false);
1219 IntPtr pNativeHome
= Marshal
.AllocCoTaskMem(allocSize
);
1221 // marshal the object as class with layout (UnmanagedType.LPStruct)
1224 StubHelpers
.FmtClassUpdateNativeInternal(pManagedHome
, (byte *)pNativeHome
.ToPointer(), ref cleanupWorkList
);
1228 backPropAction
= BackPropAction
.Layout
;
1230 layoutType
= pManagedHome
.GetType();
1237 [System
.Security
.SecurityCritical
]
1238 internal IntPtr
ConvertToNative(object pManagedHome
, int dwFlags
)
1240 if (pManagedHome
== null)
1243 if (pManagedHome
is ArrayWithOffset
)
1244 throw new ArgumentException(Environment
.GetResourceString("Arg_MarshalAsAnyRestriction"));
1248 if (pManagedHome
.GetType().IsArray
)
1251 pNativeHome
= ConvertArrayToNative(pManagedHome
, dwFlags
);
1256 StringBuilder sbValue
;
1258 if ((strValue
= pManagedHome
as string) != null)
1260 // string (LPStr or LPWStr)
1261 pNativeHome
= ConvertStringToNative(strValue
, dwFlags
);
1263 else if ((sbValue
= pManagedHome
as StringBuilder
) != null)
1265 // StringBuilder (LPStr or LPWStr)
1266 pNativeHome
= ConvertStringBuilderToNative(sbValue
, dwFlags
);
1268 else if (pManagedHome
.GetType().IsLayoutSequential
|| pManagedHome
.GetType().IsExplicitLayout
)
1270 // layout (LPStruct)
1271 pNativeHome
= ConvertLayoutToNative(pManagedHome
, dwFlags
);
1275 // this type is not supported for AsAny marshaling
1276 throw new ArgumentException(Environment
.GetResourceString("Arg_NDirectBadObject"));
1283 [System
.Security
.SecurityCritical
]
1284 internal unsafe void ConvertToManaged(object pManagedHome
, IntPtr pNativeHome
)
1286 switch (backPropAction
)
1288 case BackPropAction
.Array
:
1290 MngdNativeArrayMarshaler
.ConvertContentsToManaged(
1293 new IntPtr(&pNativeHome
));
1297 case BackPropAction
.Layout
:
1299 StubHelpers
.FmtClassUpdateCLRInternal(pManagedHome
, (byte *)pNativeHome
.ToPointer());
1303 case BackPropAction
.StringBuilderAnsi
:
1305 sbyte* ptr
= (sbyte*)pNativeHome
.ToPointer();
1306 ((StringBuilder
)pManagedHome
).ReplaceBufferAnsiInternal(ptr
, Win32Native
.lstrlenA(pNativeHome
));
1310 case BackPropAction
.StringBuilderUnicode
:
1312 char* ptr
= (char*)pNativeHome
.ToPointer();
1313 ((StringBuilder
)pManagedHome
).ReplaceBufferInternal(ptr
, Win32Native
.lstrlenW(pNativeHome
));
1317 // nothing to do for BackPropAction.None
1321 [System
.Security
.SecurityCritical
]
1322 internal void ClearNative(IntPtr pNativeHome
)
1324 if (pNativeHome
!= IntPtr
.Zero
)
1326 if (layoutType
!= null)
1328 // this must happen regardless of BackPropAction
1329 Marshal
.DestroyStructure(pNativeHome
, layoutType
);
1331 Win32Native
.CoTaskMemFree(pNativeHome
);
1333 StubHelpers
.DestroyCleanupList(ref cleanupWorkList
);
1335 } // struct AsAnyMarshaler
1337 #if FEATURE_COMINTEROP
1338 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
1339 internal static class NullableMarshaler
1342 static internal IntPtr ConvertToNative
<T
>(ref Nullable
<T
> pManaged
) where T
: struct
1344 if (pManaged
.HasValue
)
1346 object impl
= IReferenceFactory
.CreateIReference(pManaged
);
1347 return Marshal
.GetComInterfaceForObject(impl
, typeof(IReference
<T
>));
1356 static internal void ConvertToManagedRetVoid
<T
>(IntPtr pNative
, ref Nullable
<T
> retObj
) where T
: struct
1358 retObj
= ConvertToManaged
<T
>(pNative
);
1363 static internal Nullable
<T
> ConvertToManaged
<T
>(IntPtr pNative
) where T
: struct
1365 if (pNative
!= IntPtr
.Zero
)
1367 object wrapper
= InterfaceMarshaler
.ConvertToManagedWithoutUnboxing(pNative
);
1368 return (Nullable
<T
>)CLRIReferenceImpl
<T
>.UnboxHelper(wrapper
);
1372 return new Nullable
<T
>();
1375 } // class NullableMarshaler
1377 // Corresponds to Windows.UI.Xaml.Interop.TypeName
1378 [StructLayout(LayoutKind
.Sequential
)]
1379 internal struct TypeNameNative
1382 internal IntPtr typeName
; // HSTRING
1383 internal TypeKind typeKind
; // TypeKind enum
1386 // Corresponds to Windows.UI.Xaml.TypeSource
1387 internal enum TypeKind
1394 internal static class WinRTTypeNameConverter
1396 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1397 internal static extern string ConvertToWinRTTypeName(System
.Type managedType
, out bool isPrimitive
);
1399 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1400 internal static extern System
.Type
GetTypeFromWinRTTypeName(string typeName
, out bool isPrimitive
);
1403 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
1404 internal static class SystemTypeMarshaler
1407 internal static unsafe void ConvertToNative(System
.Type managedType
, TypeNameNative
*pNativeType
)
1409 if (!Environment
.IsWinRTSupported
)
1411 throw new PlatformNotSupportedException(Environment
.GetResourceString("PlatformNotSupported_WinRT"));
1415 if (managedType
!= null)
1417 if (managedType
.GetType() != typeof(System
.RuntimeType
))
1418 { // The type should be exactly System.RuntimeType (and not its child System.ReflectionOnlyType, or other System.Type children)
1419 throw new ArgumentException(Environment
.GetResourceString("Argument_WinRTSystemRuntimeType", managedType
.GetType().ToString()));
1423 string winrtTypeName
= WinRTTypeNameConverter
.ConvertToWinRTTypeName(managedType
, out isPrimitive
);
1424 if (winrtTypeName
!= null)
1426 // Must be a WinRT type, either in a WinMD or a Primitive
1427 typeName
= winrtTypeName
;
1429 pNativeType
->typeKind
= TypeKind
.Primitive
;
1431 pNativeType
->typeKind
= TypeKind
.Metadata
;
1436 typeName
= managedType
.AssemblyQualifiedName
;
1437 pNativeType
->typeKind
= TypeKind
.Projection
;
1441 { // Marshal null as empty string + Projection
1443 pNativeType
->typeKind
= TypeKind
.Projection
;
1446 int hrCreate
= System
.Runtime
.InteropServices
.WindowsRuntime
.UnsafeNativeMethods
.WindowsCreateString(typeName
, typeName
.Length
, &pNativeType
->typeName
);
1447 Marshal
.ThrowExceptionForHR(hrCreate
, new IntPtr(-1));
1451 internal static unsafe void ConvertToManaged(TypeNameNative
*pNativeType
, ref System
.Type managedType
)
1453 if (!Environment
.IsWinRTSupported
)
1455 throw new PlatformNotSupportedException(Environment
.GetResourceString("PlatformNotSupported_WinRT"));
1458 string typeName
= WindowsRuntimeMarshal
.HStringToString(pNativeType
->typeName
);
1459 if (String
.IsNullOrEmpty(typeName
))
1465 if (pNativeType
->typeKind
== TypeKind
.Projection
)
1467 managedType
= Type
.GetType(typeName
, /* throwOnError = */ true);
1472 managedType
= WinRTTypeNameConverter
.GetTypeFromWinRTTypeName(typeName
, out isPrimitive
);
1474 // TypeSource must match
1475 if (isPrimitive
!= (pNativeType
->typeKind
== TypeKind
.Primitive
))
1476 throw new ArgumentException(Environment
.GetResourceString("Argument_Unexpected_TypeSource"));
1481 internal static unsafe void ClearNative(TypeNameNative
*pNativeType
)
1483 Contract
.Assert(Environment
.IsWinRTSupported
);
1485 if (pNativeType
->typeName
!= null)
1487 System
.Runtime
.InteropServices
.WindowsRuntime
.UnsafeNativeMethods
.WindowsDeleteString(pNativeType
->typeName
);
1490 } // class SystemTypeMarshaler
1492 // For converting WinRT's Windows.Foundation.HResult into System.Exception and vice versa.
1493 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
1494 internal static class HResultExceptionMarshaler
1496 static internal unsafe int ConvertToNative(Exception ex
)
1498 if (!Environment
.IsWinRTSupported
)
1500 throw new PlatformNotSupportedException(Environment
.GetResourceString("PlatformNotSupported_WinRT"));
1509 [SecuritySafeCritical
]
1510 static internal unsafe Exception
ConvertToManaged(int hr
)
1512 Contract
.Ensures(Contract
.Result
<Exception
>() != null || hr
>= 0);
1514 if (!Environment
.IsWinRTSupported
)
1516 throw new PlatformNotSupportedException(Environment
.GetResourceString("PlatformNotSupported_WinRT"));
1522 e
= StubHelpers
.InternalGetCOMHRExceptionObject(hr
, IntPtr
.Zero
, null, /* fForWinRT */ true);
1525 // S_OK should be marshaled as null. WinRT API's should not return S_FALSE by convention.
1526 // We've chosen to treat S_FALSE as success and return null.
1527 Contract
.Assert(e
!= null || hr
== 0 || hr
== 1, "Unexpected HRESULT - it is a success HRESULT (without the high bit set) other than S_OK & S_FALSE.");
1530 } // class HResultExceptionMarshaler
1532 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
1533 internal static class KeyValuePairMarshaler
1536 internal static IntPtr ConvertToNative
<K
, V
>([In
] ref KeyValuePair
<K
, V
> pair
)
1538 IKeyValuePair
<K
, V
> impl
= new CLRIKeyValuePairImpl
<K
, V
>(ref pair
);
1539 return Marshal
.GetComInterfaceForObject(impl
, typeof(IKeyValuePair
<K
, V
>));
1543 internal static KeyValuePair
<K
, V
> ConvertToManaged
<K
, V
>(IntPtr pInsp
)
1545 object obj
= InterfaceMarshaler
.ConvertToManagedWithoutUnboxing(pInsp
);
1547 IKeyValuePair
<K
, V
> pair
= (IKeyValuePair
<K
, V
>)obj
;
1548 return new KeyValuePair
<K
, V
>(pair
.Key
, pair
.Value
);
1551 // Called from COMInterfaceMarshaler
1553 internal static object ConvertToManagedBox
<K
, V
>(IntPtr pInsp
)
1555 return (object)ConvertToManaged
<K
, V
>(pInsp
);
1557 } // class KeyValuePairMarshaler
1559 #endif // FEATURE_COMINTEROP
1561 [StructLayout(LayoutKind
.Sequential
)]
1562 internal struct NativeVariant
1569 // The union portion of the structure contains at least one 64-bit type that on some 32-bit platforms
1570 // (notably ARM) requires 64-bit alignment. So on 32-bit platforms we'll actually size the variant
1571 // portion of the struct with an Int64 so the type loader notices this requirement (a no-op on x86,
1572 // but on ARM it will allow us to correctly determine the layout of native argument lists containing
1573 // VARIANTs). Note that the field names here don't matter: none of the code refers to these fields,
1574 // the structure just exists to provide size information to the IL marshaler.
1581 } // struct NativeVariant
1583 #if !WIN64 && !FEATURE_CORECLR
1584 // Structure filled by IL stubs if copy constructor(s) and destructor(s) need to be called
1585 // on value types pushed on the stack. The structure is stored in s_copyCtorStubDesc by
1586 // SetCopyCtorCookieChain and fetched by CopyCtorCallStubWorker. Must be stack-allocated.
1587 [StructLayout(LayoutKind
.Sequential
)]
1588 unsafe internal struct CopyCtorStubCookie
1590 public void SetData(IntPtr srcInstancePtr
, uint dstStackOffset
, IntPtr ctorPtr
, IntPtr dtorPtr
)
1592 m_srcInstancePtr
= srcInstancePtr
;
1593 m_dstStackOffset
= dstStackOffset
;
1594 m_ctorPtr
= ctorPtr
;
1595 m_dtorPtr
= dtorPtr
;
1598 public void SetNext(IntPtr pNext
)
1603 public IntPtr m_srcInstancePtr
; // pointer to the source instance
1604 public uint m_dstStackOffset
; // offset from the start of stack arguments of the pushed 'this' instance
1606 public IntPtr m_ctorPtr
; // fnptr to the managed copy constructor, result of ldftn
1607 public IntPtr m_dtorPtr
; // fnptr to the managed destructor, result of ldftn
1609 public IntPtr m_pNext
; // pointer to next cookie in the chain or IntPtr.Zero
1610 } // struct CopyCtorStubCookie
1612 // Aggregates pointer to CopyCtorStubCookie and the target of the interop call.
1613 [StructLayout(LayoutKind
.Sequential
)]
1614 unsafe internal struct CopyCtorStubDesc
1616 public IntPtr m_pCookie
;
1617 public IntPtr m_pTarget
;
1618 } // struct CopyCtorStubDes
1619 #endif // !WIN64 && !FEATURE_CORECLR
1621 // Aggregates SafeHandle and the "owned" bit which indicates whether the SafeHandle
1622 // has been successfully AddRef'ed. This allows us to do realiable cleanup (Release)
1623 // if and only if it is needed.
1624 [System
.Security
.SecurityCritical
]
1625 internal sealed class CleanupWorkListElement
1627 public CleanupWorkListElement(SafeHandle handle
)
1632 public SafeHandle m_handle
;
1634 // This field is passed by-ref to SafeHandle.DangerousAddRef.
1635 // CleanupWorkList.Destroy ignores this element if m_owned is not set to true.
1636 public bool m_owned
;
1637 } // class CleanupWorkListElement
1639 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
1640 [System
.Security
.SecurityCritical
]
1641 internal sealed class CleanupWorkList
1643 private List
<CleanupWorkListElement
> m_list
= new List
<CleanupWorkListElement
>();
1645 public void Add(CleanupWorkListElement elem
)
1647 BCLDebug
.Assert(elem
.m_owned
== false, "m_owned is supposed to be false and set later by DangerousAddRef");
1651 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.Success
)]
1652 public void Destroy()
1654 for (int i
= m_list
.Count
- 1; i
>= 0; i
--)
1656 if (m_list
[i
].m_owned
)
1657 StubHelpers
.SafeHandleRelease(m_list
[i
].m_handle
);
1660 } // class CleanupWorkList
1662 [System
.Security
.SecurityCritical
] // auto-generated
1663 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.MayFail
)]
1664 [SuppressUnmanagedCodeSecurityAttribute()]
1665 internal static class StubHelpers
1667 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1668 static internal extern bool IsQCall(IntPtr pMD
);
1670 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1671 static internal extern void InitDeclaringType(IntPtr pMD
);
1673 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1674 static internal extern IntPtr
GetNDirectTarget(IntPtr pMD
);
1676 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1677 static internal extern IntPtr
GetDelegateTarget(Delegate pThis
, ref IntPtr pStubArg
);
1679 #if !WIN64 && !FEATURE_CORECLR
1680 // Written to by a managed stub helper, read by CopyCtorCallStubWorker in VM.
1682 static CopyCtorStubDesc s_copyCtorStubDesc
;
1684 static internal void SetCopyCtorCookieChain(IntPtr pStubArg
, IntPtr pUnmngThis
, int dwStubFlags
, IntPtr pCookie
)
1686 // we store both the cookie chain head and the target of the copy ctor stub to a thread
1687 // static field to be accessed by the copy ctor (see code:CopyCtorCallStubWorker)
1688 s_copyCtorStubDesc
.m_pCookie
= pCookie
;
1689 s_copyCtorStubDesc
.m_pTarget
= GetFinalStubTarget(pStubArg
, pUnmngThis
, dwStubFlags
);
1692 // Returns the final unmanaged stub target, ignores interceptors.
1693 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1694 static internal extern IntPtr
GetFinalStubTarget(IntPtr pStubArg
, IntPtr pUnmngThis
, int dwStubFlags
);
1695 #endif // !FEATURE_CORECLR && !WIN64
1697 #if !FEATURE_CORECLR
1698 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1699 static internal extern void DemandPermission(IntPtr pNMD
);
1700 #endif // !FEATURE_CORECLR
1702 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1703 static internal extern void SetLastError();
1705 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1706 static internal extern void ThrowInteropParamException(int resID
, int paramIdx
);
1708 [System
.Security
.SecurityCritical
]
1709 static internal IntPtr
AddToCleanupList(ref CleanupWorkList pCleanupWorkList
, SafeHandle handle
)
1711 if (pCleanupWorkList
== null)
1712 pCleanupWorkList
= new CleanupWorkList();
1714 CleanupWorkListElement element
= new CleanupWorkListElement(handle
);
1715 pCleanupWorkList
.Add(element
);
1717 // element.m_owned will be true iff the AddRef succeeded
1718 return SafeHandleAddRef(handle
, ref element
.m_owned
);
1721 [System
.Security
.SecurityCritical
]
1722 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.Success
)]
1723 static internal void DestroyCleanupList(ref CleanupWorkList pCleanupWorkList
)
1725 if (pCleanupWorkList
!= null)
1727 pCleanupWorkList
.Destroy();
1728 pCleanupWorkList
= null;
1732 static internal Exception
GetHRExceptionObject(int hr
)
1734 Exception ex
= InternalGetHRExceptionObject(hr
);
1735 ex
.InternalPreserveStackTrace();
1739 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1740 static internal extern Exception
InternalGetHRExceptionObject(int hr
);
1742 #if FEATURE_COMINTEROP
1743 static internal Exception
GetCOMHRExceptionObject(int hr
, IntPtr pCPCMD
, object pThis
)
1745 Exception ex
= InternalGetCOMHRExceptionObject(hr
, pCPCMD
, pThis
, false);
1746 ex
.InternalPreserveStackTrace();
1750 static internal Exception
GetCOMHRExceptionObject_WinRT(int hr
, IntPtr pCPCMD
, object pThis
)
1752 Exception ex
= InternalGetCOMHRExceptionObject(hr
, pCPCMD
, pThis
, true);
1753 ex
.InternalPreserveStackTrace();
1757 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1758 static internal extern Exception
InternalGetCOMHRExceptionObject(int hr
, IntPtr pCPCMD
, object pThis
, bool fForWinRT
);
1760 #endif // FEATURE_COMINTEROP
1762 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1763 static internal extern IntPtr
CreateCustomMarshalerHelper(IntPtr pMD
, int paramToken
, IntPtr hndManagedType
);
1765 //-------------------------------------------------------
1766 // SafeHandle Helpers
1767 //-------------------------------------------------------
1769 // AddRefs the SH and returns the underlying unmanaged handle.
1770 [System
.Security
.SecurityCritical
] // auto-generated
1771 static internal IntPtr
SafeHandleAddRef(SafeHandle pHandle
, ref bool success
)
1773 if (pHandle
== null)
1775 throw new ArgumentNullException(Environment
.GetResourceString("ArgumentNull_SafeHandle"));
1777 Contract
.EndContractBlock();
1779 pHandle
.DangerousAddRef(ref success
);
1781 return (success
? pHandle
.DangerousGetHandle() : IntPtr
.Zero
);
1784 // Releases the SH (to be called from finally block).
1785 [System
.Security
.SecurityCritical
] // auto-generated
1786 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.Success
)]
1787 static internal void SafeHandleRelease(SafeHandle pHandle
)
1789 if (pHandle
== null)
1791 throw new ArgumentNullException(Environment
.GetResourceString("ArgumentNull_SafeHandle"));
1793 Contract
.EndContractBlock();
1797 pHandle
.DangerousRelease();
1800 catch (Exception ex
)
1802 Mda
.ReportErrorSafeHandleRelease(ex
);
1804 #else // MDA_SUPPORTED
1807 #endif // MDA_SUPPORTED
1810 #if FEATURE_COMINTEROP
1811 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1812 static internal extern IntPtr
GetCOMIPFromRCW(object objSrc
, IntPtr pCPCMD
, out IntPtr ppTarget
, out bool pfNeedsRelease
);
1814 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1815 static internal extern IntPtr
GetCOMIPFromRCW_WinRT(object objSrc
, IntPtr pCPCMD
, out IntPtr ppTarget
);
1817 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1818 static internal extern IntPtr
GetCOMIPFromRCW_WinRTSharedGeneric(object objSrc
, IntPtr pCPCMD
, out IntPtr ppTarget
);
1820 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1821 static internal extern IntPtr
GetCOMIPFromRCW_WinRTDelegate(object objSrc
, IntPtr pCPCMD
, out IntPtr ppTarget
);
1823 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1824 static internal extern bool ShouldCallWinRTInterface(object objSrc
, IntPtr pCPCMD
);
1826 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1827 static internal extern Delegate
GetTargetForAmbiguousVariantCall(object objSrc
, IntPtr pMT
, out bool fUseString
);
1829 //-------------------------------------------------------
1830 // Helper for the MDA ----OnRCWCleanup
1831 //-------------------------------------------------------
1833 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1834 static internal extern void StubRegisterRCW(object pThis
);
1836 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1837 static internal extern void StubUnregisterRCW(object pThis
);
1839 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1840 static internal extern IntPtr
GetDelegateInvokeMethod(Delegate pThis
);
1842 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1843 [System
.Security
.SecurityCritical
]
1844 static internal extern object GetWinRTFactoryObject(IntPtr pCPCMD
);
1846 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1847 [System
.Security
.SecurityCritical
]
1848 static internal extern IntPtr
GetWinRTFactoryReturnValue(object pThis
, IntPtr pCtorEntry
);
1850 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1851 [System
.Security
.SecurityCritical
]
1852 static internal extern IntPtr
GetOuterInspectable(object pThis
, IntPtr pCtorMD
);
1855 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1856 static internal extern Exception
TriggerExceptionSwallowedMDA(Exception ex
, IntPtr pManagedTarget
);
1857 #endif // MDA_SUPPORTED
1859 #endif // FEATURE_COMINTEROP
1862 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1863 static internal extern void CheckCollectedDelegateMDA(IntPtr pEntryThunk
);
1864 #endif // MDA_SUPPORTED
1866 //-------------------------------------------------------
1868 //-------------------------------------------------------
1869 #if PROFILING_SUPPORTED
1870 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1871 static internal extern IntPtr
ProfilerBeginTransitionCallback(IntPtr pSecretParam
, IntPtr pThread
, object pThis
);
1873 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1874 static internal extern void ProfilerEndTransitionCallback(IntPtr pMD
, IntPtr pThread
);
1875 #endif // PROFILING_SUPPORTED
1877 //------------------------------------------------------
1879 //------------------------------------------------------
1880 static internal void CheckStringLength(int length
)
1882 CheckStringLength((uint)length
);
1885 static internal void CheckStringLength(uint length
)
1887 if (length
> 0x7ffffff0)
1889 throw new MarshalDirectiveException(Environment
.GetResourceString("Marshaler_StringTooLong"));
1893 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1894 static internal unsafe extern int strlen(sbyte* ptr
);
1896 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1897 static internal extern void DecimalCanonicalizeInternal(ref Decimal dec
);
1899 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1900 static internal unsafe extern void FmtClassUpdateNativeInternal(object obj
, byte* pNative
, ref CleanupWorkList pCleanupWorkList
);
1901 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1902 static internal unsafe extern void FmtClassUpdateCLRInternal(object obj
, byte* pNative
);
1903 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1904 static internal unsafe extern void LayoutDestroyNativeInternal(byte* pNative
, IntPtr pMT
);
1905 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1906 static internal extern object AllocateInternal(IntPtr typeHandle
);
1908 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1909 static internal extern void MarshalToUnmanagedVaListInternal(IntPtr va_list
, uint vaListSize
, IntPtr pArgIterator
);
1911 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1912 static internal extern void MarshalToManagedVaListInternal(IntPtr va_list
, IntPtr pArgIterator
);
1914 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1915 static internal extern uint CalcVaListSize(IntPtr va_list
);
1917 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1918 static internal extern void ValidateObject(object obj
, IntPtr pMD
, object pThis
);
1920 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1921 static internal extern void LogPinnedArgument(IntPtr localDesc
, IntPtr nativeArg
);
1923 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1924 static internal extern void ValidateByref(IntPtr byref
, IntPtr pMD
, object pThis
); // the byref is pinned so we can safely "cast" it to IntPtr
1926 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1927 static internal extern IntPtr
GetStubContext();
1930 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1931 static internal extern IntPtr
GetStubContextAddr();
1935 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1936 static internal extern void TriggerGCForMDA();
1937 #endif // MDA_SUPPORTED
1939 #if FEATURE_ARRAYSTUB_AS_IL
1940 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1941 internal static extern void ArrayTypeCheck(object o
, Object
[] arr
);
1944 #if FEATURE_STUBS_AS_IL
1945 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1946 internal static extern void MulticastDebuggerTraceHelper(object o
, Int32 count
);
1948 } // class StubHelpers