diff --git a/S7.Net.UnitTest/S7NetTestsAsync.cs b/S7.Net.UnitTest/S7NetTestsAsync.cs
index 31f99eb..86d7f22 100644
--- a/S7.Net.UnitTest/S7NetTestsAsync.cs
+++ b/S7.Net.UnitTest/S7NetTestsAsync.cs
@@ -160,6 +160,31 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
}
+ [TestMethod]
+ public async Task Test_Async_ReadAndWriteNestedClass()
+ {
+ Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
+
+ TestClassWithNestedClass tc = new TestClassWithNestedClass
+ {
+ BitVariable00 = true,
+ BitVariable01 = new TestClassInnerWithBool { BitVariable00 = true },
+ ByteVariable02 = new TestClassInnerWithByte { ByteVariable00 = 128 },
+ BitVariable03 = true,
+ ShortVariable04 = new TestClassInnerWithShort { ShortVarialbe00 = -15000 }
+ };
+
+ await plc.WriteClassAsync(tc, DB4);
+ TestClassWithNestedClass tc2 = new TestClassWithNestedClass();
+ // Values that are read from a class are stored inside the class itself, that is passed by reference
+ await plc.ReadClassAsync(tc2, DB4);
+ Assert.AreEqual(tc.BitVariable00, tc2.BitVariable00);
+ Assert.AreEqual(tc.BitVariable01.BitVariable00, tc2.BitVariable01.BitVariable00);
+ Assert.AreEqual(tc.ByteVariable02.ByteVariable00, tc2.ByteVariable02.ByteVariable00);
+ Assert.AreEqual(tc.BitVariable03, tc2.BitVariable03);
+ Assert.AreEqual(tc.ShortVariable04.ShortVarialbe00, tc2.ShortVariable04.ShortVarialbe00);
+ }
+
///
/// Read/Write a struct that has the same properties of a DB with the same field in the same order
///
diff --git a/S7.Net.UnitTest/S7NetTestsSync.cs b/S7.Net.UnitTest/S7NetTestsSync.cs
index 1b648f2..c096643 100644
--- a/S7.Net.UnitTest/S7NetTestsSync.cs
+++ b/S7.Net.UnitTest/S7NetTestsSync.cs
@@ -718,6 +718,31 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc.ShortVariable04.ShortVarialbe00, tc2.ShortVariable04.ShortVarialbe00);
}
+ [TestMethod]
+ public void T32_ReadAndWriteNestedClass()
+ {
+ Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
+
+ TestClassWithNestedClass tc = new TestClassWithNestedClass
+ {
+ BitVariable00 = true,
+ BitVariable01 = new TestClassInnerWithBool { BitVariable00 = true },
+ ByteVariable02 = new TestClassInnerWithByte { ByteVariable00 = 128 },
+ BitVariable03 = true,
+ ShortVariable04 = new TestClassInnerWithShort { ShortVarialbe00 = -15000 }
+ };
+
+ plc.WriteClass(tc, DB4);
+ TestClassWithNestedClass tc2 = new TestClassWithNestedClass();
+ // Values that are read from a class are stored inside the class itself, that is passed by reference
+ plc.ReadClass(tc2, DB4);
+ Assert.AreEqual(tc.BitVariable00, tc2.BitVariable00);
+ Assert.AreEqual(tc.BitVariable01.BitVariable00, tc2.BitVariable01.BitVariable00);
+ Assert.AreEqual(tc.ByteVariable02.ByteVariable00, tc2.ByteVariable02.ByteVariable00);
+ Assert.AreEqual(tc.BitVariable03, tc2.BitVariable03);
+ Assert.AreEqual(tc.ShortVariable04.ShortVarialbe00, tc2.ShortVariable04.ShortVarialbe00);
+ }
+
[TestMethod, ExpectedException(typeof(PlcException))]
public void T18_ReadStructThrowsIfPlcIsNotConnected()
{
diff --git a/S7.Net/PlcAsynchronous.cs b/S7.Net/PlcAsynchronous.cs
index f3457ae..1c28503 100644
--- a/S7.Net/PlcAsynchronous.cs
+++ b/S7.Net/PlcAsynchronous.cs
@@ -370,8 +370,9 @@ namespace S7.Net
/// A task that represents the asynchronous write operation.
public async Task WriteClassAsync(object classValue, int db, int startByteAdr = 0)
{
- var bytes = Types.Class.ToBytes(classValue).ToList();
- await WriteBytesAsync(DataType.DataBlock, db, startByteAdr, bytes.ToArray());
+ byte[] bytes = new byte[(int)Class.GetClassSize(classValue)];
+ Types.Class.ToBytes(classValue, bytes);
+ await WriteBytesAsync(DataType.DataBlock, db, startByteAdr, bytes);
}
private async Task ReadBytesWithSingleRequestAsync(DataType dataType, int db, int startByteAdr, int count)
diff --git a/S7.Net/Types/Class.cs b/S7.Net/Types/Class.cs
index c1dc14f..227a521 100644
--- a/S7.Net/Types/Class.cs
+++ b/S7.Net/Types/Class.cs
@@ -239,7 +239,7 @@ namespace S7.Net.Types
return numBytes;
}
- private static void ToBytes(object propertyValue, byte[] bytes, ref double numBytes)
+ private static double SetBytesFromProperty(object propertyValue, byte[] bytes, double numBytes)
{
int bytePos = 0;
int bitPos = 0;
@@ -282,7 +282,7 @@ namespace S7.Net.Types
bytes2 = Single.ToByteArray((float)propertyValue);
break;
default:
- bytes2 = ToBytes(propertyValue);
+ numBytes = ToBytes(propertyValue, bytes, numBytes);
break;
}
@@ -297,6 +297,8 @@ namespace S7.Net.Types
bytes[bytePos + bCnt] = bytes2[bCnt];
numBytes += bytes2.Length;
}
+
+ return numBytes;
}
///
@@ -304,12 +306,8 @@ namespace S7.Net.Types
///
/// The struct object
/// A byte array or null if fails.
- public static byte[] ToBytes(object sourceClass)
+ public static double ToBytes(object sourceClass, byte[] bytes, double numBytes = 0.0)
{
- int size = (int)GetClassSize(sourceClass);
- byte[] bytes = new byte[size];
- double numBytes = 0.0;
-
var properties = GetAccessableProperties(sourceClass.GetType());
foreach (var property in properties)
{
@@ -319,15 +317,15 @@ namespace S7.Net.Types
Type elementType = property.PropertyType.GetElementType();
for (int i = 0; i < array.Length && numBytes < bytes.Length; i++)
{
- ToBytes(array.GetValue(i), bytes, ref numBytes);
+ numBytes = SetBytesFromProperty(array.GetValue(i), bytes, numBytes);
}
}
else
{
- ToBytes(property.GetValue(sourceClass, null), bytes, ref numBytes);
+ numBytes = SetBytesFromProperty(property.GetValue(sourceClass, null), bytes, numBytes);
}
}
- return bytes;
+ return numBytes;
}
}
}