Netlogix 7.0如何读取带长度的UDT标签并解析为结构体数组?
解决方案
首先需要确保结构体的内存布局和PLC中的存储对齐规则一致,先修正结构体定义:
[StructLayout(LayoutKind.Sequential, Pack = 1)] public struct STRUCT_A { public bool Active; public int Value; }
读取PLC标签并转换为结构体数组
方式一:使用Marshal内存转换(适配PLC内存布局完全匹配的场景)
// 初始化PLC连接(以EthernetIP为例,根据你的INGEAR驱动类型调整) var plc = new EthernetIPClient("PLC_IP_ADDRESS"); plc.Connect(); // 读取标签的原始字节数组 byte[] rawBytes = plc.Read(MyTags); // 转换为STRUCT_A数组 STRUCT_A[] structArray = ConvertBytesToStructArray(rawBytes); // 遍历数组处理数据 foreach (var item in structArray) { // 示例输出逻辑,可根据需求修改 Console.WriteLine($"Active: {item.Active}, Value: {item.Value}"); } // 字节转结构体数组的核心函数 private static STRUCT_A[] ConvertBytesToStructArray(byte[] bytes) { int structSize = Marshal.SizeOf(typeof(STRUCT_A)); int arrayLength = bytes.Length / structSize; STRUCT_A[] result = new STRUCT_A[arrayLength]; GCHandle pinnedHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); try { IntPtr basePtr = pinnedHandle.AddrOfPinnedObject(); for (int i = 0; i < arrayLength; i++) { result[i] = Marshal.PtrToStructure<STRUCT_A>(basePtr + i * structSize); } } finally { pinnedHandle.Free(); } return result; }
方式二:手动解析字节(灵活适配不同字节序/对齐规则)
如果PLC的内存对齐或字节序和本地环境不一致,手动解析更可控:
// 读取字节数组的代码同上 byte[] rawBytes = plc.Read(MyTags); STRUCT_A[] structArray = ConvertBytesToStructArrayManual(rawBytes); // 手动转换函数 private static STRUCT_A[] ConvertBytesToStructArrayManual(byte[] bytes) { // 单个STRUCT_A的字节大小,需根据PLC实际存储规则调整(示例为1字节bool + 4字节int = 5字节) int structByteSize = 5; int arrayLength = bytes.Length / structByteSize; STRUCT_A[] result = new STRUCT_A[arrayLength]; for (int i = 0; i < arrayLength; i++) { int offset = i * structByteSize; // 解析bool:PLC中通常非0值表示true result[i].Active = bytes[offset] != 0; // 解析int:默认适配小端字节序,若PLC为大端需反转字节 result[i].Value = BitConverter.ToInt32(bytes, offset + 1); // 大端字节序处理示例: // byte[] intBytes = new byte[4]; // Array.Copy(bytes, offset + 1, intBytes, 0, 4); // Array.Reverse(intBytes); // result[i].Value = BitConverter.ToInt32(intBytes, 0); } return result; }
关键注意事项
- 结构体的
Pack参数必须和PLC的内存对齐规则一致,若PLC采用4字节对齐,需将Pack设为4,此时结构体总大小会变为8字节(bool占1字节,填充3字节后存储int)。 - 确认PLC的字节序(大端/小端),手动解析时对应调整字节顺序。
- 确保读取的字节数组长度是单个结构体字节数的整数倍,避免数据截断。
内容的提问来源于stack exchange,提问作者cszynkowski
相关产品推荐
相关产品推荐

