7

我正在开发 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# 结构,但我认为他们没有真正测试过它,因为它不起作用。这是我第一次与工会打交道,所以我不确定如何处理。我的知识范围来自过去几周的研究。

如果有人能提供一些见解,我将不胜感激。

4

3 回答 3

1

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

  1. 对齐(1、2、4 字节)

  2. 尺寸和偏移量

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

[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

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

  [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。

于 2013-06-08T11:50:54.570 回答
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[] 作为匿名数据的联合。然后当我们进行调用时,我们可以使用 NET_DVR_STREAM_MODE 中的 byGetStreamType 作为开关,将 byte[] 解析/转换为适当的类型。

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

于 2013-06-19T21:01:27.400 回答
0

我不确定,但尺寸可能不对。如果 528 基于 32 位指针,而您使用 64 位指针进行编译,则大小会很小。然后其中之一STRUCT_X struX可能是“溢出”结构。

它在什么时候抛出异常?就在程序启动时或您第一次尝试制作其中一个union_amain_struct

于 2013-06-07T18:41:05.230 回答