diff --git a/Core/Extensions/InteropExtensions.cs b/Core/Extensions/InteropExtensions.cs index 8196cfc2..2c0eabaa 100644 --- a/Core/Extensions/InteropExtensions.cs +++ b/Core/Extensions/InteropExtensions.cs @@ -322,7 +322,7 @@ namespace Vanara.Extensions /// /// The optional function to unlock memory after assignment. /// A pointer to the memory allocated by . - public static IntPtr MarshalToPtr(this T value, Func memAlloc, out int bytesAllocated, int prefixBytes = 0, Func memLock = null, Action memUnlock = null) + public static IntPtr MarshalToPtr(this T value, Func memAlloc, out int bytesAllocated, int prefixBytes = 0, Func memLock = null, Func memUnlock = null) { memLock ??= Passthrough; if (VanaraMarshaler.CanMarshal(typeof(T), out IVanaraMarshaler marshaler)) @@ -364,7 +364,7 @@ namespace Vanara.Extensions /// The optional function to unlock memory after assignment. /// Pointer to the allocated native (unmanaged) array of items stored. /// Structure layout is not sequential or explicit. - public static IntPtr MarshalToPtr(this IEnumerable items, Func memAlloc, out int bytesAllocated, int prefixBytes = 0, Func memLock = null, Action memUnlock = null) + public static IntPtr MarshalToPtr(this IEnumerable items, Func memAlloc, out int bytesAllocated, int prefixBytes = 0, Func memLock = null, Func memUnlock = null) { if (!typeof(T).IsMarshalable()) throw new ArgumentException(@"Structure layout is not sequential or explicit."); @@ -401,7 +401,7 @@ namespace Vanara.Extensions /// The optional function to unlock memory after assignment. /// Pointer to the allocated native (unmanaged) array of items stored. /// Structure layout is not sequential or explicit. - public static IntPtr MarshalToPtr(this T[] items, Func memAlloc, out int bytesAllocated, int prefixBytes = 0, Func memLock = null, Action memUnlock = null) => + public static IntPtr MarshalToPtr(this T[] items, Func memAlloc, out int bytesAllocated, int prefixBytes = 0, Func memLock = null, Func memUnlock = null) => MarshalToPtr(items.Cast(), memAlloc, out bytesAllocated, prefixBytes, memLock, memUnlock); /// @@ -424,7 +424,7 @@ namespace Vanara.Extensions /// Pointer to the allocated native (unmanaged) array of strings stored using the model and the character /// set defined by . /// - public static IntPtr MarshalToPtr(this IEnumerable values, StringListPackMethod packing, Func memAlloc, out int bytesAllocated, CharSet charSet = CharSet.Auto, int prefixBytes = 0, Func memLock = null, Action memUnlock = null) + public static IntPtr MarshalToPtr(this IEnumerable values, StringListPackMethod packing, Func memAlloc, out int bytesAllocated, CharSet charSet = CharSet.Auto, int prefixBytes = 0, Func memLock = null, Func memUnlock = null) { memLock ??= Passthrough; @@ -469,7 +469,7 @@ namespace Vanara.Extensions /// Pointer to the allocated native (unmanaged) array of strings stored using the model and the character /// set defined by . /// - public static IntPtr MarshalToPtr(this string[] values, StringListPackMethod packing, Func memAlloc, out int bytesAllocated, CharSet charSet = CharSet.Auto, int prefixBytes = 0, Func memLock = null, Action memUnlock = null) => + public static IntPtr MarshalToPtr(this string[] values, StringListPackMethod packing, Func memAlloc, out int bytesAllocated, CharSet charSet = CharSet.Auto, int prefixBytes = 0, Func memLock = null, Func memUnlock = null) => MarshalToPtr((IEnumerable)values, packing, memAlloc, out bytesAllocated, charSet, prefixBytes, memLock, memUnlock); /// Adds an offset to the value of a pointer. @@ -714,9 +714,13 @@ namespace Vanara.Extensions if (lptr == IntPtr.Zero) yield break; var charLength = StringHelper.GetCharSize(charSet); var i = prefixBytes; - if (allocatedBytes == 0) allocatedBytes = SizeT.MaxValue; + if (allocatedBytes == 0) + allocatedBytes = SizeT.MaxValue; + else if (allocatedBytes - prefixBytes - charLength < 0) + throw new InsufficientMemoryException(); // handle condition where there is just the null terminator - if (allocatedBytes - prefixBytes - charLength <= 0) yield break; + else if (allocatedBytes - prefixBytes - charLength == 0 && GetCh(lptr.Offset(prefixBytes)) == 0) + yield break; for (IntPtr ptr = lptr.Offset(i); i + charLength <= allocatedBytes && GetCh(ptr) != 0; i += charLength, ptr = lptr.Offset(i)) { for (IntPtr cptr = ptr; i + charLength <= allocatedBytes && GetCh(cptr) != 0; cptr = cptr.Offset(charLength), i += charLength) { }