[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern unsafe void __Memmove(byte* dest, byte* src, nuint len);
+
+ // Used by ilmarshalers.cpp
+ internal static unsafe void Memcpy(byte* pDest, int destIndex, byte[] src, int srcIndex, int len)
+ {
+ Debug.Assert((srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
+ Debug.Assert(src.Length - srcIndex >= len, "not enough bytes in src");
+ // If dest has 0 elements, the fixed statement will throw an
+ // IndexOutOfRangeException. Special-case 0-byte copies.
+ if (len == 0)
+ return;
+ fixed (byte* pSrc = src)
+ {
+ Memcpy(pDest + destIndex, pSrc + srcIndex, len);
+ }
+ }
}
}
}
else
{
- // Otherwise we use a slower "2-pass" mode where we first marshal the string into an intermediate buffer
- // (managed byte array) and then allocate exactly the right amount of unmanaged memory. This is to avoid
- // wasting memory on systems with multibyte character sets where the buffer we end up with is often much
- // smaller than the upper bound for the given managed string.
+ if (strManaged.Length == 0)
+ {
+ nb = 0;
+ pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(2);
+ }
+ else
+ {
+ // Otherwise we use a slower "2-pass" mode where we first marshal the string into an intermediate buffer
+ // (managed byte array) and then allocate exactly the right amount of unmanaged memory. This is to avoid
+ // wasting memory on systems with multibyte character sets where the buffer we end up with is often much
+ // smaller than the upper bound for the given managed string.
- byte[] bytes = AnsiCharMarshaler.DoAnsiConversion(strManaged,
- fBestFit: 0 != (flags & 0xFF), fThrowOnUnmappableChar: 0 != (flags >> 8), out nb);
+ byte[] bytes = AnsiCharMarshaler.DoAnsiConversion(strManaged,
+ fBestFit: 0 != (flags & 0xFF), fThrowOnUnmappableChar: 0 != (flags >> 8), out nb);
- // + 1 for the null character from the user. + 1 for the null character we put in.
- pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb + 2);
+ // + 1 for the null character from the user. + 1 for the null character we put in.
+ pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb + 2);
- Buffer.Memcpy(pbNativeBuffer, 0, bytes, 0, nb);
+ fixed (byte* pBytes = &bytes[0])
+ {
+ Buffer.Memcpy(pbNativeBuffer, pBytes, nb);
+ }
+ }
}
pbNativeBuffer[nb] = 0x00;
byte[] bytes = AnsiCharMarshaler.DoAnsiConversion(strManaged, fBestFit, fThrowOnUnmappableChar, out nbytesused);
Debug.Assert(nbytesused < nbytes, "Insufficient buffer allocated in VBByValStrMarshaler.ConvertToNative");
- Buffer.Memcpy(pNative, 0, bytes, 0, nbytesused);
+ fixed (byte* pBytes = &bytes[0])
+ {
+ Buffer.Memcpy(pNative, pBytes, nbytesused);
+ }
pNative[nbytesused] = 0;
*pLength = nbytesused;
Memmove((byte*)destination, (byte*)source, checked((nuint)sourceBytesToCopy));
}
- internal static unsafe void Memcpy(byte[] dest, int destIndex, byte* src, int srcIndex, int len)
- {
- Debug.Assert((srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
- Debug.Assert(dest.Length - destIndex >= len, "not enough bytes in dest");
- // If dest has 0 elements, the fixed statement will throw an
- // IndexOutOfRangeException. Special-case 0-byte copies.
- if (len == 0)
- return;
- fixed (byte* pDest = dest)
- {
- Memcpy(pDest + destIndex, src + srcIndex, len);
- }
- }
-
- internal static unsafe void Memcpy(byte* pDest, int destIndex, byte[] src, int srcIndex, int len)
- {
- Debug.Assert((srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
- Debug.Assert(src.Length - srcIndex >= len, "not enough bytes in src");
- // If dest has 0 elements, the fixed statement will throw an
- // IndexOutOfRangeException. Special-case 0-byte copies.
- if (len == 0)
- return;
- fixed (byte* pSrc = src)
- {
- Memcpy(pDest + destIndex, pSrc + srcIndex, len);
- }
- }
-
// This method has different signature for x64 and other platforms and is done for performance reasons.
internal static unsafe void Memmove(byte* dest, byte* src, nuint len)
{