C#调用C++的dll,Marshal.PtrToStructure引发类型为“System.ExecutionEngineException”的错误

C#调用C++的dll,Marshal.PtrToStructure引发类型为“System.ExecutionEngineException”的异常。

       [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
        public struct NET_DVR_PICCFG_V30
        {
            public uint dwSize;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = Hik_HCNetSDK.NAME_LEN)]
            public byte[] sChanName;
            public uint dwVideoFormat;
            public NET_DVR_COLOR struColor;
            public string reservedData;
            public uint dwShowChanName;
            public ushort wShowNameTopLeftX;
            public ushort wShowNameTopLeftY;
            public NET_DVR_VILOST_V30 struVILost;
            public NET_DVR_VILOST_V30 struRes;
            public NET_DVR_MOTION_V30 struMotion;
            public NET_DVR_HIDEALARM_V30 struHideAlarm;
            public uint dwEnableHide;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = Hik_HCNetSDK.MAX_SHELTERNUM)]
            public NET_DVR_SHELTER[] struShelter;
            public uint dwShowOsd;
            public ushort wOSDTopLeftX;
            public ushort wOSDTopLeftY;
            public byte byOSDType;
            public byte byDispWeek;
            public byte byOSDAttrib;
            public byte byHourOSDType;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
            public byte[] byRes;
        }

其中 NET_DVR_VILOST_V30 等定义类似于NET_DVR_PICCFG_V30这个结构。
之后我调用如下代码

NET_DVR_PICCFG_V30 picCfg = new NET_DVR_PICCFG_V30();
int size = Marshal.SizeOf(picCfg);
byte[] bPicCfg = new byte[size];

//即调用某个函数从C++的Dll获取到结构体的bPicCfg,如果这个函数调用失败或者不调用,则不会出现问题。
dvr.DVR_GetDVRConfig(Hik_HCNetSDK.NET_DVR_GET_PICCFG_V30, 1, bPicCfg, out outBufferSize, out byteReturned);
IntPtr ipPicCfg = Marshal.AllocHGlobal(size);
Marshal.Copy(bPicCfg, 0, ipPicCfg, bPicCfg.Length);

//问题出现在这里。运行时报 引发类型为“System.ExecutionEngineException”的异常。 这个错误。
picCfg = (NET_DVR_PICCFG_V30)Marshal.PtrToStructure(ipPicCfg, picCfg.GetType());


第一次发贴,诚心希望各位牛人帮忙解答。这个问题已经困扰我好几天了,先谢过大家。
------解决方案--------------------
建议你和同事商讨。

至少存在几个问题:
1、reservedData的声明一定有问题:
public struct NET_DVR_PICCFG_V30
{
  ...
  public string reservedData;
  ...
}

2、dwOutBufferSize是一个数字,不可以是指针
[DllImport("HCNetSDK.dll")]
public static extern bool NET_DVR_GetDVRConfig(int lUserID, uint dwCommand,
int lChannel, byte[] lpOutBuffer, out uint dwOutBufferSize, out uint lpBytesReturned);

3、可能可以直接传递ref NET_DVR_PICCFG_V30 lpOutBuffer,而不用麻烦Marshal.PtrToStructure
------解决方案--------------------
这样转换:

public struct NET_DVR_MOTION_V30
{
    public IntPtr byMotionScope;                   //这里要换成指针
    public byte byMotionSensitive;                 /*移动侦测灵敏度, 0 - 5,越高越灵敏,oxff关闭*/
    public byte byEnableHandleMotion;              /* 是否处理移动侦测 0-否 1-是*/ 
    public byte byRes;                             /* 保留 */