C#中的C Union错误与非对象字段错误对齐或重叠

时间:2013-06-07 18:29:51

标签: c# data-structures struct marshalling unions

我正在使用C#WPF应用程序并尝试使用非托管dll(无权访问源代码)。我需要的结构是'NET_DVR_IPPARACFG_V40',其中包含一堆其他结构/联合。以下是文档提供给我们的信息:

struct{
  DWORD                   dwSize;
  DWORD                   dwGroupNum;
  DWORD                   dwAChanNum;
  DWORD                   dwDChanNum;
  DWORD                   dwStartDChan;
  BYTE                    byAnalogChanEnable[MAX_CHANNUM_V30];
  NET_DVR_IPDEVINFO_V31   struIPDevInfo[MAX_IP_DEVICE_V40];
  NET_DVR_STREAM_MODE     struStreamMode[MAX_CHANNUM_V30];
  BYTE                    byRes2[20];
}NET_DVR_IPPARACFG_V40

struct{
  BYTE               byEnable;
  BYTE               byProType;
  BYTE               byEnableQuickAdd;
  BYTE               byRes1;
  BYTE               sUserName[NAME_LEN];
  BYTE               sPassword[PASSWD_LEN];
  BYTE               byDomain[MAX_DOMAIN_NAME];
  NET_DVR_IPADDR     struIP;
  WORD               wDVRPort;
  BYTE               byRes2[34];
}NET_DVR_IPDEVINFO_V31

struct{
  char    sIpV4[16];
  BYTE    sIpV6[128];
}NET_DVR_IPADDR

struct{
  BYTE                      byGetStreamType;
  BYTE                      byRes[3];
  NET_DVR_GET_STREAM_UNION  uGetStream;
}NET_DVR_STREAM_MODE

union{
  NET_DVR_IPCHANINFO          struChanInfo;
  NET_DVR_IPSERVER_STREAM     struIPServerStream;
  NET_DVR_PU_STREAM_CFG       struPUStream;
  NET_DVR_DDNS_STREAM_CFG     struDDNSStream;
  NET_DVR_PU_STREAM_URL       struStreamUrl;
  NET_DVR_HKDDNS_STREAM       struHkDDNSStream;
}NET_DVR_GET_STREAM_UNION

struct{
  BYTE     byEnable;
  BYTE     byIPID;
  BYTE     byChannel;
  BYTE     byIPIDHigh;
  BYTE     byRes[32];
}NET_DVR_IPCHANINFO

struct{
  BYTE               byEnable;
  BYTE               byRes[3];
  NET_DVR_IPADDR     struIPServer;
  WORD               wPort;
  WORD               wDvrNameLen;
  BYTE               byDVRName[NAME_LEN];
  WORD               wDVRSerialLen;
  WORD               byRes1[2];
  BYTE               byDVRSerialNumber[SERIALNO_LEN];
  BYTE               byUserName[NAME_LEN];
  BYTE               byPassWord[PASSWD_LEN];
  BYTE               byChannel;
  BYTE               byRes2[11];
}NET_DVR_IPSERVER_STREAM

struct{
  DWORD                             dwSize;
  NET_DVR_STREAM_MEDIA_SERVER_CFG   struStreamMediaSvrCfg;
  NET_DVR_DEV_CHAN_INFO             struDevChanInfo;
}NET_DVR_PU_STREAM_CFG

struct{
  NET_DVR_IPADDR   struIP;
  WORD             wDVRPort;
  BYTE             byChannel;
  BYTE             byTransProtocol;
  BYTE             byTransMode;
  BYTE             byFactoryType; 
  BYTE             byDeviceType;
  BYTE             byDispChan;
  BYTE             bySubDispChan; 
  BYTE             byRes[3];
  BYTE             byDomain[MAX_DOMAIN_NAME]; 
  BYTE             sUserName[NAME_LEN];
  BYTE             sPassword[PASSWD_LEN];
}NET_DVR_DEV_CHAN_INFO

struct{
  DWORD                             dwSize;
  NET_DVR_STREAM_MEDIA_SERVER_CFG   struStreamMediaSvrCfg;
  NET_DVR_DEV_CHAN_INFO             struDevChanInfo;
}NET_DVR_PU_STREAM_CFG

struct{
  BYTE             byValid;
  BYTE             byRes1[3];
  NET_DVR_IPADDR   struDevIP;
  WORD             wDevPort;
  BYTE             byTransmitType;
  BYTE             byRes2[69];
}NET_DVR_STREAM_MEDIA_SERVER_CFG

struct{
  BYTE               byEnable;
  BYTE               byRes1[3];
  NET_DVR_IPADDR     struStreamServer;
  WORD               wStreamServerPort;
  BYTE               byStreamServerTransmitType;
  BYTE               byRes2;
  NET_DVR_IPADDR     struIPServer;
  WORD               wIPServerPort;
  BYTE               byRes3[2];
  BYTE               sDVRName[NAME_LEN];
  WORD               wDVRNameLen;
  WORD               wDVRSerialLen;
  BYTE               sDVRSerialNumber[SERIALNO_LEN];
  BYTE               sUserName[NAME_LEN];
  BYTE               sPassWord[PASSWD_LEN];
  WORD               wDVRPort;
  BYTE               byRes4[2];
  BYTE               byChannel;
  BYTE               byTransProtocol;
  BYTE               byTransMode;
  BYTE               byFactoryType;
}NET_DVR_DDNS_STREAM_CFG

struct{
  BYTE    byEnable;
  BYTE    strURL[240];
  BYTE    byTransPortocol ;
  WORD    wIPID;
  BYTE    byChannel;
  BYTE    byRes[7];
}NET_DVR_PU_STREAM_URL

struct{
  BYTE    byEnable;
  BYTE    byRes[3];
  BYTE    byDDNSDomain[64];
  WORD    wPort;
  WORD    wAliasLen;
  BYTE    byAlias[NAME_LEN];
  WORD    wDVRSerialLen;
  BYTE    byRes1[2];
  BYTE    byDVRSerialNumber[SERIALNO_LEN];
  BYTE    byUserName[NAME_LEN];
  BYTE    byPassWord[PASSWD_LEN];
  BYTE    byChannel;
  BYTE    byRes2[11];
}NET_DVR_HKDDNS_STREAM

我在网上阅读了大量的文档,但似乎无法正确地将“NET_DVR_IPPARACFG_V40”编组。这是我在C#中所拥有的:

/*[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_IPPARACFG_V40
{
    public uint dwSize;
    public uint dwGroupNum;
    public uint dwAChanNum;
    public uint dwDChanNum;
    public uint dwStartDChan;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = MAX_CHANNUM_V30, ArraySubType = UnmanagedType.I1)]
    public byte[] byAnalogChanEnable;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = MAX_IP_DEVICE_V40, ArraySubType = UnmanagedType.Struct)]
    public NET_DVR_IPDEVINFO_V31[] struIPDevInfo;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = MAX_CHANNUM_V30, ArraySubType = UnmanagedType.Struct)]
    public NET_DVR_STREAM_MODE[] struStreamMode;
    public byte[] byRes2;
}*/
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public struct NET_DVR_IPPARACFG_V40
{
    public uint dwSize;
    public uint dwGroupNum;
    public uint dwAChanNum;
    public uint dwDChanNum;
    public uint dwStartDChan;
    unsafe public fixed byte byAnalogChanEnable[MAX_CHANNUM_V30];
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = MAX_IP_DEVICE_V40, ArraySubType = UnmanagedType.Struct)]
    public NET_DVR_IPDEVINFO_V31[] struIPDevInfo;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = MAX_CHANNUM_V30, ArraySubType = UnmanagedType.Struct)]
    public NET_DVR_STREAM_MODE[] struStreamMode;
    unsafe public fixed byte byRes2[20];
}

/*[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_IPDEVINFO_V31
{
    public byte byEnable;
    public byte byProType;
    public byte byEnableQuickAdd;
    public byte byRes1;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NAME_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] sUserName;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = PASSWD_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] sPassword;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = MAX_DOMAIN_NAME, ArraySubType = UnmanagedType.I1)]
    public byte[] byDomain;
    public NET_DVR_IPADDR struIP;
    public ushort wDVRPort;
    public byte[] byRes;
}*/
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public struct NET_DVR_IPDEVINFO_V31
{
    public byte byEnable;
    public byte byProType;
    public byte byEnableQuickAdd;
    public byte byRes1;
    unsafe public fixed byte sUserName[NAME_LEN];
    unsafe public fixed byte sPassword[PASSWD_LEN];
    unsafe public fixed byte byDomain[MAX_DOMAIN_NAME];
    public NET_DVR_IPADDR struIP;
    public ushort wDVRPort;
    unsafe public fixed byte byRes[34];
}

/*[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_STREAM_MODE
{
    public byte byGetStreamType;
    public byte[] byRes;
    public NET_DVR_GET_STREAM_UNION uGetStream;
}*/
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public struct NET_DVR_STREAM_MODE
{
    public byte byGetStreamType;
    unsafe public fixed byte byRes[3];
    public NET_DVR_GET_STREAM_UNION uGetStream;
}

/*[StructLayout(LayoutKind.Explicit, Size = 528)]
public struct NET_DVR_GET_STREAM_UNION
{
    [FieldOffset(0)]
    public NET_DVR_IPCHANINFO struChanInfo;
    [FieldOffset(0)]
    public NET_DVR_IPSERVER_STREAM struIPServerStream;
    [FieldOffset(0)]
    public NET_DVR_PU_STREAM_CFG struPUStream;
    [FieldOffset(0)]
    public NET_DVR_DDNS_STREAM_CFG struDDNSStream;
    [FieldOffset(0)]
    public NET_DVR_PU_STREAM_URL struStreamUrl;
    [FieldOffset(0)]
    public NET_DVR_HKDDNS_STREAM struHkDDNSStream;
}*/
[StructLayout(LayoutKind.Explicit)]
public struct NET_DVR_GET_STREAM_UNION
{
    [FieldOffset(0)]
    public NET_DVR_IPCHANINFO struChanInfo;
    [FieldOffset(0)]
    public NET_DVR_IPSERVER_STREAM struIPServerStream;
    [FieldOffset(0)]
    public NET_DVR_PU_STREAM_CFG struPUStream;
    [FieldOffset(0)]
    public NET_DVR_DDNS_STREAM_CFG struDDNSStream;
    [FieldOffset(0)]
    public NET_DVR_PU_STREAM_URL struStreamUrl;
    [FieldOffset(0)]
    public NET_DVR_HKDDNS_STREAM struHkDDNSStream;
}

/*[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct NET_DVR_IPADDR
{

    /// char[16]
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string sIpV4;

    /// BYTE[128]
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 128, ArraySubType = UnmanagedType.I1)]
    public byte[] byRes;

    public void Init()
    {
        byRes = new byte[128];
    }
}*/
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public struct NET_DVR_IPADDR
{
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string sIpV4;
    unsafe public fixed byte byRes[128];
}

/*[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_DEV_CHAN_INFO
{
    public NET_DVR_IPADDR struIP;
    public ushort wDVRPort;
    public byte byChannel;
    public byte byTransProtocol;
    public byte byTransMode;
    public byte byFactoryType;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I1)]
    public byte[] byRes;
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = MAX_DOMAIN_NAME)]
    public string byDomain;
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = NAME_LEN)]
    public string sUserName;
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = PASSWD_LEN)]
    public string sPassword;
}*/
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public struct NET_DVR_DEV_CHAN_INFO
{
    public NET_DVR_IPADDR struIP;
    public ushort wDVRPort;
    public byte byChannel;
    public byte byTransProtocol;
    public byte byTransMode;
    public byte byFactoryType;
    unsafe public fixed byte byRes[6];
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = MAX_DOMAIN_NAME)]
    public string byDomain;
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = NAME_LEN)]
    public string sUserName;
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = PASSWD_LEN)]
    public string sPassword;
}

/*[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_STREAM_MEDIA_SERVER_CFG
{
    public byte byValid;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.I1)]
    public byte[] byRes1;
    public NET_DVR_IPADDR struDevIP;
    public ushort wDevPort;
    public byte byTransmitType;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 69, ArraySubType = UnmanagedType.I1)]
    public byte[] byRes2;
}*/
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public struct NET_DVR_STREAM_MEDIA_SERVER_CFG
{
    public byte byValid;
    unsafe public fixed byte byRes1[3];
    public NET_DVR_IPADDR struDevIP;
    public ushort wDevPort;
    public byte byTransmitType;
    unsafe public fixed byte byRes2[69];
}



/*[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_IPCHANINFO
{
    public byte byEnable;
    public byte byIPID;
    public byte byChannel;
    public byte byProType;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.I1)]
    public byte[] byRes;
    public void Init()
    {
        byRes = new byte[32];
    }
}*/
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public struct NET_DVR_IPCHANINFO
{
    public byte byEnable;
    public byte byIPID;
    public byte byChannel;
    public byte byProType;
    unsafe public fixed byte byRes[32];
}

/*[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_IPSERVER_STREAM
{
    public byte byEnable;
    public byte[] byRes;
    public NET_DVR_IPADDR struIPServer;
    public ushort wPort;
    public ushort wDvrNameLen;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NAME_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] byDVRName;
    public ushort wDVRSerialLen;
    public ushort[] byRes1;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = SERIALNO_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] byDVRSerialNumber;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NAME_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] byUserName;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = PASSWD_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] byPassWord;
    public byte byChannel;
    public byte[] byRes2;
}*/
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public struct NET_DVR_IPSERVER_STREAM
{
    public byte byEnable;
    unsafe public fixed byte byRes[3];
    public NET_DVR_IPADDR struIPServer;
    public ushort wPort;
    public ushort wDvrNameLen;
    unsafe public fixed byte byDVRName[NAME_LEN];
    public ushort wDVRSerialLen;
    unsafe public fixed ushort byRes1[2];
    unsafe public fixed byte byDVRSerialNumber[SERIALNO_LEN];
    unsafe public fixed byte byUserName[NAME_LEN];
    unsafe public fixed byte byPassWord[PASSWD_LEN];
    public byte byChannel;
    unsafe public fixed byte byRes2[11];
}

/*[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_PU_STREAM_CFG
{
    public uint dwSize;
    public NET_DVR_STREAM_MEDIA_SERVER_CFG struStreamMediaSvrCfg;
    public NET_DVR_DEV_CHAN_INFO struDevChanInfo;
}*/
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public unsafe struct NET_DVR_PU_STREAM_CFG
{
    public uint dwSize;
    public NET_DVR_STREAM_MEDIA_SERVER_CFG struStreamMediaSvrCfg;
    public NET_DVR_DEV_CHAN_INFO struDevChanInfo;
}

/*[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_DDNS_STREAM_CFG
{
    public byte byEnable;
    public byte[] byRes1;
    public NET_DVR_IPADDR struStreamServer;
    public ushort wStreamServerPort;
    public byte byStreamServerTransmitType;
    public byte byRes2;
    public NET_DVR_IPADDR struIPServer;
    public byte wIPServerPort;
    public byte[] byRes3;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NAME_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] sDVRName;
    public ushort wDVRNameLen;
    public ushort wDVRSerialLen;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = SERIALNO_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] sDVRSerialNumber;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NAME_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] sUserName;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = PASSWD_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] sPassWord;
    public ushort wDVRPort;
    public byte[] byRes4;
    public byte byChannel;
    public byte byTransProtocol;
    public byte byTransMode;
    public byte byFactoryType;
}*/
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public struct NET_DVR_DDNS_STREAM_CFG
{
    public byte byEnable;
    unsafe public fixed byte byRes1[3];
    public NET_DVR_IPADDR struStreamServer;
    public ushort wStreamServerPort;
    public byte byStreamServerTransmitType;
    public byte byRes2;
    public NET_DVR_IPADDR struIPServer;
    public byte wIPServerPort;
    unsafe public fixed byte byRes3[2];
    unsafe public fixed byte sDVRName[NAME_LEN];
    public ushort wDVRNameLen;
    public ushort wDVRSerialLen;
    unsafe public fixed byte sDVRSerialNumber[SERIALNO_LEN];
    unsafe public fixed byte sUserName[NAME_LEN];
    unsafe public fixed byte sPassWord[PASSWD_LEN];
    public ushort wDVRPort;
    unsafe public fixed byte byRes4[2];
    public byte byChannel;
    public byte byTransProtocol;
    public byte byTransMode;
    public byte byFactoryType;
}

/*[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_PU_STREAM_URL
{
    public byte byEnable;
    public byte[] strURL;
    public byte byTransPortocol;
    public ushort wIPID;
    public byte byChannel;
    public byte[] byRes;
}*/
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public struct NET_DVR_PU_STREAM_URL
{
    public byte byEnable;
    unsafe public fixed byte strURL[240];
    public byte byTransPortocol;
    public ushort wIPID;
    public byte byChannel;
    unsafe public fixed byte byRes[7];
}

/*[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_HKDDNS_STREAM
{
    public byte byEnable;
    public byte[] byRes;
    public byte[] byDDNSDomain;
    public ushort wPort;
    public ushort wAliasLen;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NAME_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] byAlias;
    public ushort wDVRSerialLen;
    public byte[] byRes1;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = SERIALNO_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] byDVRSerialNumber;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NAME_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] byUserName;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = PASSWD_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] byPassWord;
    public byte byChannel;
    public byte[] byRes2;
}*/
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public struct NET_DVR_HKDDNS_STREAM
{
    public byte byEnable;
    unsafe public fixed byte byRes[3];
    unsafe public fixed byte byDDNSDomain[64];
    public ushort wPort;
    public ushort wAliasLen;
    unsafe public fixed byte byAlias[NAME_LEN];
    public ushort wDVRSerialLen;
    unsafe public fixed byte byRes1[2];
    unsafe public fixed byte byDVRSerialNumber[SERIALNO_LEN];
    unsafe public fixed byte byUserName[NAME_LEN];
    unsafe public fixed byte byPassWord[PASSWD_LEN];
    public byte byChannel;
    unsafe public fixed byte byRes2[11];
}

它编译但是当我进行使用此结构的调用时,我得到错误“无法加载类型,因为它包含偏移0处的对象字段,该字段未正确对齐或由非对象字段重叠。”工会中的结构也是不同的尺寸,我不确定这是否是一个问题但是值得注意。制造商实际上给了我上面的C#结构,但我认为他们没有真正测试它,因为它不起作用。这是我第一次与工会打交道,所以我不确定如何处理它。我的知识范围来自过去几周内的研究。

如果有人能提供一些见解,我会非常感激。

3 个答案:

答案 0 :(得分:1)

在编组时,我们应该注意两件事:

  1. 对齐(1,2,4字节)
  2. 尺寸和偏移量

    每当我们遇到像BYTE,WORD,BYTE [69]这样不是4字节(32位)的值 对齐我们应该明确地对齐:

  3. [StructLayout(LayoutKind.Sequential, Pack = 1)] // <- Pack = 1, byte border alignment 
    

    每当我们有像BYTE这样的数组[69]时,我们应该通知.Net关于数组的大小, 那样:

    fixed byte byRes2[69]; // <- do not move (re-align) 69 bytes! And address them as array
    

    最后,我们可以通过sizeof()函数检查我们是否已经完成了所有工作。 例如,让我们编组一个给定的结构

      struct{
        BYTE             byValid;
        BYTE             byRes1[3];
        NET_DVR_IPADDR   struDevIP;
        WORD             wDevPort;
        BYTE             byTransmitType;
        BYTE             byRes2[69];
      }NET_DVR_STREAM_MEDIA_SERVER_CFG
    

    我们可以看到,它具有非平凡的对齐(因为结构包含单个字节,单词, 不是4 *字节值的数组)以及数组。所以C#wrap将是

      [StructLayout(LayoutKind.Sequential, Pack = 1)]
      public unsafe struct NET_DVR_STREAM_MEDIA_SERVER_CFG {
        byte       byValid;
        fixed byte byRes1[3];
        int        struDevIP; // <- I suggest IP v4 using here (Int32)
        UInt16     wDevPort;
        byte       byTransmitType;
        fixed byte byRes2[69];
      }
    

    是时候检查一下:初始结构大小使用1 + 3 + 4 + 2 + 1 + 69 = 80字节, 实际大小是

    sizeof(NET_DVR_STREAM_MEDIA_SERVER_CFG) 
    

    返回80。

答案 1 :(得分:1)

在别人的帮助下,我们终于得到了结构。以下是涉及联盟的2个结构:

[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_GET_STREAM_UNION
{
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 492, ArraySubType = UnmanagedType.I1)]
    public byte[] byUnion;
    public void Init()
    {
        byUnion = new byte[492];
    }
}

[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_STREAM_MODE
{  
    public byte  byGetStreamType;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.I1)]
    public byte[]  byRes;
    public NET_DVR_GET_STREAM_UNION uGetStream;
    public void Init()
    {
        byGetStreamType = 0;
        byRes = new byte[3];
        uGetStream.Init();
    }
}

基本上,我们只使用byte []作为匿名数据的union。然后当我们进行调用时,我们可以使用NET_DVR_STREAM_MODE中的byGetStreamType作为开关来解析/转换byte []到适当的类型。

感谢所有帮助过的人提供的意见。

答案 2 :(得分:0)

我不确定,但尺寸可能不合适。如果528基于32位指针并且您使用64位指针进行编译,则大小将会很小。其中一个STRUCT_X struX可能会“溢出”结构。

在什么时候抛出异常?在程序启动时或首次尝试制作union_a s / main_struct s之一时?