Bri*_*ian 7 c# struct marshalling unions data-structures
我正在使用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
Run Code Online (Sandbox Code Playgroud)
我已经在网上阅读了大量的文档,但仍然无法正确地将这个"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];
}
Run Code Online (Sandbox Code Playgroud)
它编译,但当我进行使用此结构的调用时,我得到错误"无法加载类型,因为它包含偏移0处的对象字段,该字段未正确对齐或由非对象字段重叠." 工会中的结构也是不同的尺寸,我不确定这是否是一个问题但是值得注意.制造商实际上给了我上面的C#结构,但我不认为他们真的测试过它,因为它不起作用.这是我第一次与工会打交道,所以我不确定如何处理它.我的知识范围来自过去几周内的研究.
如果有人能提供一些见解,我会非常感激.
在其他人的帮助下,我们终于把结构搞定了。以下是处理联合的 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();
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,我们只是使用 byte[] 作为匿名数据的联合。然后,当我们进行调用时,我们可以使用 NET_DVR_STREAM_MODE 中的 byGetStreamType 作为开关,将 byte[] 解析/转换为适当的类型。
感谢所有提供帮助的人的意见。
| 归档时间: |
|
| 查看次数: |
2166 次 |
| 最近记录: |