1,博图数据块的数据排列原则:
数据对齐算法:将当前地址对齐到整数:
numBytes = (int)Math.Ceiling(numBytes);将当前地址对齐到偶整数:
numBytes = Math.Ceiling(numBytes);
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
numBytes++;
2,数据对齐的原则,如果当前的数据类型是:bool,则使用当前地址.
byte,则使用对齐方式1
其他,则使用对齐方式2,即偶数对齐的方法.
3,如何从地址和bool进行设定和取值,假设我们有一个byte[]数组代表整个DB,和一个浮点数代表bool的地址?取值:
int bytePos = (int)Math.Floor(numBytes);
int bitPos = (int)((numBytes - (double)bytePos) / 0.125);
if ((bytes[bytePos] & (int)Math.Pow(2, bitPos)) != 0)
value = true;
else
value = false;
赋值bytePos = (int)Math.Floor(numBytes);
bitPos = (int)((numBytes - (double)bytePos) / 0.125);
if ((bool)obj)
bytes[bytePos] |= (byte)Math.Pow(2, bitPos); // is true
else
bytes[bytePos] &= (byte)(~(byte)Math.Pow(2, bitPos)); // is false
思路:获取当前bit所在的字节地址.然后使用 (注意位是从0开始的.位0..位15..位31.)
t=t | 1<
t=t &(~1<
t=t^(1<
t=t&(1<
2,迭代解析
numbytes: 迭代的plc地址
itemInfos:迭代的信息存储的列表
preName:迭代的名称.
ElementItem:用于解析的元素.
public static void DeserializeItem(ref double numBytes, List itemInfos, string preName, ElementItem item)
{
var PreName = (string.IsNullOrEmpty(preName)) ? "" : preName + "_";
var Info = new ItemInfo() { Name = PreName + item.Name, Type = item.Type };
switch (item.GetTypeInfo())
{
case PlcParamType.BaseType:
switch (item.Type)
{
case "Bool":
Info.Addr = ParseAddr(numBytes, item);
numBytes += 0.125;
break;
case "Char":
case "Byte":
numBytes = Math.Ceiling(numBytes);
Info.Addr = ParseAddr(numBytes, item);
numBytes++;
;
break;
case "Int":
case "UInt":
case "Word":
numBytes = Math.Ceiling(numBytes);
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
numBytes++;
Info.Addr = ParseAddr(numBytes, item);
numBytes += 2;
;
break;
case "DInt":
case "UDInt":
case "DWord":
case "Time":
case "Real":
numBytes = Math.Ceiling(numBytes);
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
numBytes++;
Info.Addr = ParseAddr(numBytes, item);
numBytes += 4;
;
break;
default:
break;
}
itemInfos.Add(Info);
break;
case PlcParamType.String:
numBytes = Math.Ceiling(numBytes);
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
numBytes++;
//----------
Info.Addr = ParseAddr(numBytes, item);
numBytes += item.GetStringLength();
itemInfos.Add(Info);
break;
case PlcParamType.Array:
//------------原程序的可能是个漏洞.
numBytes = Math.Ceiling(numBytes);
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
numBytes++;
//-------------
var elementType = item.GetElementType();
for (var i = 0; i < item.GetArrayLength(); i++)
{
var element = new ElementItem() { Name = item.Name + $"[{i}