I have the following code and I'm new to Marshaling in .Net and have no idea why the Marshal.StructureToPtr only works when I allocate > 32 bytes to Marshal.AllocHGlobal. Anything <= 32, throw "Attempted to read or write protected memory. This is often an indication that other memory is corrupt.".
I need the size of the array in both structure are dynamic.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
namespace LPArrayMarshalTest
{
class Program
{
static void Main(string[] args)
{
try
{
SubInfo sInfo = new SubInfo();
sInfo.SubID = Encoding.ASCII.GetBytes("SUB1");
sInfo.ArrayOfItem = new ushort[1] { 1 };
MainInfo mInfo = new MainInfo();
mInfo.ArrayOfSubItem = new SubInfo[1] { sInfo };
mInfo.MainID = Encoding.ASCII.GetBytes("MAIN");
int mInfoSize = 0;
mInfoSize += mInfo.MainID.Length;
foreach (SubInfo sub in mInfo.ArrayOfSubItem)
{
int sInfoSize = sub.SubID.Length + (sub.ArrayOfItem.Length * Marshal.SizeOf(typeof(ushort)));
mInfoSize += sInfoSize;
}
IntPtr mInfoPtr = Marshal.AllocHGlobal(mInfoSize * 3); //throw error
//IntPtr mInfoPtr = Marshal.AllocHGlobal(mInfoSize * 4); //No Error
Marshal.StructureToPtr(mInfo, mInfoPtr, true);
Marshal.FreeHGlobal(mInfoPtr);
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
Console.ReadLine();
}
}
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct MainInfo
{
[MarshalAs(UnmanagedType.SafeArray)]
public byte[] MainID;
[MarshalAs(UnmanagedType.SafeArray,
SafeArraySubType = VarEnum.VT_RECORD,
SafeArrayUserDefinedSubType = typeof(SubInfo))]
public SubInfo[] ArrayOfSubItem;
}
[ComVisible(true)]
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct SubInfo
{
[MarshalAs(UnmanagedType.SafeArray)]
public byte[] SubID;
[MarshalAs(UnmanagedType.SafeArray)]
public ushort[] ArrayOfItem;
}
}
Thanks in advance.