/// <summary> /// Creates a byte array depending on the struct type. /// </summary> /// <param name="sourceClass">The struct object</param> /// <returns>A byte array or null if fails.</returns> public static byte[] ToBytes(object sourceClass) { Type type = sourceClass.GetType(); int size = GetClassSize(type); byte[] bytes = new byte[size]; byte[] bytes2 = null; int bytePos = 0; int bitPos = 0; double numBytes = 0.0; var properties = sourceClass.GetType().GetProperties(); foreach (var property in properties) { bytes2 = null; switch (property.PropertyType.Name) { case "Boolean": // get the value bytePos = (int)Math.Floor(numBytes); bitPos = (int)((numBytes - (double)bytePos) / 0.125); if ((bool)property.GetValue(sourceClass, null)) { bytes[bytePos] |= (byte)Math.Pow(2, bitPos); // is true } else { bytes[bytePos] &= (byte)(~(byte)Math.Pow(2, bitPos)); // is false } numBytes += 0.125; break; case "Byte": numBytes = (int)Math.Ceiling(numBytes); bytePos = (int)numBytes; bytes[bytePos] = (byte)property.GetValue(sourceClass, null); numBytes++; break; case "Int16": bytes2 = Int.ToByteArray((Int16)property.GetValue(sourceClass, null)); break; case "UInt16": bytes2 = Word.ToByteArray((UInt16)property.GetValue(sourceClass, null)); break; case "Int32": bytes2 = DInt.ToByteArray((Int32)property.GetValue(sourceClass, null)); break; case "UInt32": bytes2 = DWord.ToByteArray((UInt32)property.GetValue(sourceClass, null)); break; case "Double": bytes2 = Double.ToByteArray((double)property.GetValue(sourceClass, null)); break; } if (bytes2 != null) { // add them numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) { numBytes++; } bytePos = (int)numBytes; for (int bCnt = 0; bCnt < bytes2.Length; bCnt++) { bytes[bytePos + bCnt] = bytes2[bCnt]; } numBytes += bytes2.Length; } } return(bytes); }
/// <summary> /// Creates a byte array depending on the struct type. /// </summary> /// <param name="structValue">The struct object</param> /// <returns>A byte array or null if fails.</returns> public static byte[] ToBytes(object structValue) { Type type = structValue.GetType(); int size = Struct.GetStructSize(type); byte[] bytes = new byte[size]; byte[] bytes2 = null; int bytePos = 0; int bitPos = 0; double numBytes = 0.0; System.Reflection.FieldInfo[] infos = type.GetFields(); foreach (System.Reflection.FieldInfo info in infos) { bytes2 = null; switch (info.FieldType.Name) { case "Boolean": // get the value bytePos = (int)Math.Floor(numBytes); bitPos = (int)((numBytes - (double)bytePos) / 0.125); if ((bool)info.GetValue(structValue)) { bytes[bytePos] |= (byte)Math.Pow(2, bitPos); // is true } else { bytes[bytePos] &= (byte)(~(byte)Math.Pow(2, bitPos)); // is false } numBytes += 0.125; break; case "Byte": numBytes = (int)Math.Ceiling(numBytes); bytePos = (int)numBytes; bytes[bytePos] = (byte)info.GetValue(structValue); numBytes++; break; case "Int16": bytes2 = Int.ToByteArray((Int16)info.GetValue(structValue)); break; case "UInt16": bytes2 = Word.ToByteArray((UInt16)info.GetValue(structValue)); break; case "Int32": bytes2 = DInt.ToByteArray((Int32)info.GetValue(structValue)); break; case "UInt32": bytes2 = DWord.ToByteArray((UInt32)info.GetValue(structValue)); break; case "Double": bytes2 = Double.ToByteArray((double)info.GetValue(structValue)); break; } if (bytes2 != null) { // add them numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) { numBytes++; } bytePos = (int)numBytes; for (int bCnt = 0; bCnt < bytes2.Length; bCnt++) { bytes[bytePos + bCnt] = bytes2[bCnt]; } numBytes += bytes2.Length; } } return(bytes); }
public bool WriteItems(Tag tag, object value) { lock (this) { try { if (!IsConnected()) { return(false); } if (tag.TagType == "string") //在创建TagType时已经转为小写 { var pLcAddress = DbAddress[tag.Address]; var strValue = value.ToString(); var strlen = (byte)strValue.Length; var valueByte = new byte[strlen + 1]; var strbyte = Encoding.ASCII.GetBytes(strValue); if (strbyte.Length != strlen) { throw new InvalidOperationException("写入" + tag.Address + "出错,解析的字符串长度与GetBytes数组长度不一致!"); } if (strlen > pLcAddress.BitOffset) { throw new InvalidOperationException("写入" + tag.Address + "出错,输入的字符串的长度过长!"); } valueByte[0] = strlen; strbyte.CopyTo(valueByte, 1); _plc.Write(DataType.DataBlock, pLcAddress.DBBlockID, pLcAddress.Offset + 1, valueByte); /*if (result != ErrorCode.NoError) * throw new InvalidOperationException(result + "\n" + "Tag: " + tag.Address);*/ return(true); } //2020/6/11 ByteArray if (tag.TagType == "bytearray") //在创建TagType时已经转为小写 { var pLcAddress = DbAddress[tag.Address]; var strValue = value.ToString(); var strlen = strValue.Length; var valueByte = new byte[strlen]; var strbyte = Encoding.ASCII.GetBytes(strValue); if (strbyte.Length != strlen) { throw new InvalidOperationException("写入" + tag.Address + "出错,解析的字符串长度与GetBytes数组长度不一致!"); } if (strlen != pLcAddress.BitOffset) { throw new InvalidOperationException("写入" + tag.Address + "出错,输入的字符串长度与定义长度不匹配!"); } strbyte.CopyTo(valueByte, 0); _plc.WriteBytes(DataType.DataBlock, pLcAddress.DBBlockID, pLcAddress.Offset, valueByte); /*if (result != ErrorCode.NoError) * throw new InvalidOperationException(result + "\n" + "Tag: " + tag.Address);*/ return(true); } else { switch (value) { case double d: { var bytes = Double.ToByteArray(d); value = DWord.FromByteArray(bytes); break; } case bool b: value = b ? 1 : 0; break; } _plc.Write(tag.Address, value); /*if (result != ErrorCode.NoError) * throw new InvalidOperationException(result + "\n" + "Tag: " + tag.Address);*/ return(true); } } catch (Exception ex) { //LOG.Error(string.Format("S7 Driver写入地址{0},值{1},出错{2}", tag.Address, value,ex)); Log.Error($"S7 Driver writes address:{tag.Address}, value:{value}, Message:{ex}"); return(false); } } }