我想了解如何解决我的问题的最佳方法。我有一些想法,但在我看来它们远非完美,也许有人可以建议一个干净利落的方法来做到这一点。
下图说明了我的一般代码结构
我有一个通信模块,可以将数据写入由数据字节组成的数组。我希望将结构保持原样,因为它是一个灵活的完全GUI独立解决方案。只是为了进一步解释我的原因 - 数据结构代表外部硬件单元(MCU)的物理内存。
之后我需要将这些数据拆分为属性。这意味着我有几个属性绑定到GUI中的元素,为它们提供数据。因此,我希望每个属性从数组中的特定区域获取数据作为示例索引100:104。
对我来说有问题的部分是如何以上述方式将这些属性绑定到数组?绑定需要双向。
答案 0 :(得分:1)
我不确定这是否是你需要的,但看起来你可以使用这样的方法:
您可以创建一些实现属性的结构:
[StructLayout(LayoutKind.Explicit, Size = 11, Pack = 0)]
public struct MyStructure
{
public string StringFromBytes
{
get
{
if (ByteArrayField == null || ByteArrayField.Length == 0)
{
return string.Empty;
}
return Utilitites.BytesToString(ByteArrayField);
}
}
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] [FieldOffset(0)] public byte[] ByteArrayField;
[MarshalAs(UnmanagedType.U2)] [FieldOffset(8)] public ushort WordField;
[MarshalAs(UnmanagedType.I1)] [FieldOffset(10)] public sbyte dBm0;
}
这里我们有一个由11个字节组成的结构。此结构具有对数据进行一些操作的属性。您需要确定字段的起始位置(FieldOffset())以及如何解释数据(例如UnmanagedType.U2 - 2字节无符号整数)。
当您从设备接收字节数组时,您可以轻松地将该数组转换为您的结构:
public static T ToStructure<T>(this byte[] bytes) where T : struct
{
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
var stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
handle.Free();
return stuff;
}
用法:
byte[] responseBytes = Utilitites.GetResponseFromDevice();
MyStructure response = responseDecodedBytes.ToStructure<MyStructure>();
希望这会有所帮助。