C# 转换:结构-->;字节[]->;字符串-->;字节[]->;结构给出的浮点值不正确

C# 转换:结构-->;字节[]->;字符串-->;字节[]->;结构给出的浮点值不正确,c#,string,struct,byte,C#,String,Struct,Byte,这是我的第一篇帖子,所以请让我知道下次做得更好 我试图通过串行总线以字节数组的形式发送数据。我检查了好几个帖子,但似乎没有一个适合我。我开始制作一个用于测试转换的快速控制台应用程序 这是我希望通过串行端口接收的结构: public struct DataStructSend { public UInt32 int1; public UInt32 int2; public UInt32 int3; public float float1; public fl

这是我的第一篇帖子,所以请让我知道下次做得更好

我试图通过串行总线以字节数组的形式发送数据。我检查了好几个帖子,但似乎没有一个适合我。我开始制作一个用于测试转换的快速控制台应用程序

这是我希望通过串行端口接收的结构:

public struct DataStructSend
{
    public UInt32 int1;
    public UInt32 int2;
    public UInt32 int3;
    public float float1;
    public float float2;
    public float float3;
}
首先,我首先生成一个伪字符串,其中包含接收数据的结构的字节[]

以下是生成所述字符串的代码:

//Just generating dummy serial data to "read"
List<byte> data = new List<byte>();

DataStructSend dataStruct = new DataStructSend();

UInt32 int1 = 1;
UInt32 int2 = 2;
UInt32 int3 = 3;
float float1 = 16524.0000003F;
float float2 = 13524.0000002F;
float float3 = 25524.0000001F;



byte[] byteLine = BitConverter.GetBytes(int1);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(int2);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(int3);
data.AddRange(GetByteList(byteLine));

byteLine = BitConverter.GetBytes(float1);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(float2);
data.AddRange(GetByteList(byteLine));
byteLine = BitConverter.GetBytes(float3);
data.AddRange(GetByteList(byteLine));

byte[] dataBytes = data.ToArray();

data.Add(0x0A);
Debug.WriteLine(data.Count());


for (int i = dataBytes.Count()-1; i >=0; i--)
{
    Debug.Write(dataBytes[i] + " ");
}
Debug.WriteLine("");

string line = System.Text.Encoding.Default.GetString(dataBytes);



//Here we have the Serial "received data"
            
Debug.Write("The data is -->");
Debug.Write(line);
Debug.WriteLine("<--");
结果表明,只有uint32变量完全匹配:

Sent Bytes (24)         --> 70 199 104 0 70 83 80 0 70 129 24 0 0 0 0 3 0 0 0 2 0 0 0 1 
Received Bytes (24)     --> 70 63 104 0 70 83 80 0 70 63 24 0 0 0 0 3 0 0 0 2 0 0 0 1 
int1 = 1
int2 = 2
int3 = 3
float1 = 12230
float2 = 13524
float3 = 12250
是什么导致了这个问题?或者有谁有更有效的解决方案将基于结构的数据包从8位微控制器传输到64位字应用程序

以下是完整的代码:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace ConverstionTest
{
    class Program
    {
        public static List<byte> GetByteList(byte[] array)
        {
            List<byte> returnList = new List<byte>();
            for (int i = 0; i < array.Count(); i++)
            {
                Debug.Write(array[i] + " ");
                returnList.Add(array[i]);
            }
            Debug.WriteLine("");
            return returnList;
        }

        public struct DataStructSend
        {
            public UInt32 int1;
            public UInt32 int2;
            public UInt32 int3;
            public float float1;
            public float float2;
            public float float3;
        }

        public static byte[] GetBytes(DataStructSend str)
        {
            int size = Marshal.SizeOf(str);
            byte[] arr = new byte[size];

            IntPtr ptr = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(str, ptr, true);
            Marshal.Copy(ptr, arr, 0, size);
            Marshal.FreeHGlobal(ptr);
            return arr;
        }

        public static DataStructSend FromBytes(byte[] arr)
        {
            DataStructSend str = new DataStructSend();

            int size = Marshal.SizeOf(str);
            IntPtr ptr = Marshal.AllocHGlobal(size);

            Marshal.Copy(arr, 0, ptr, size);

            str = (DataStructSend)Marshal.PtrToStructure(ptr, str.GetType());
            Marshal.FreeHGlobal(ptr);

            return str;
        }

        static void Main(string[] args)
        {
            Debug.WriteLine("Started...");


            //Just generating dummy serial data to "read"
            List<byte> data = new List<byte>();

            DataStructSend dataStruct = new DataStructSend();

            UInt32 int1 = 1;
            UInt32 int2 = 2;
            UInt32 int3 = 3;
            float float1 = 16524.0000003F;
            float float2 = 13524.0000002F;
            float float3 = 25524.0000001F;



            byte[] byteLine = BitConverter.GetBytes(int1);
            data.AddRange(GetByteList(byteLine));
            byteLine = BitConverter.GetBytes(int2);
            data.AddRange(GetByteList(byteLine));
            byteLine = BitConverter.GetBytes(int3);
            data.AddRange(GetByteList(byteLine));

            byteLine = BitConverter.GetBytes(float1);
            data.AddRange(GetByteList(byteLine));
            byteLine = BitConverter.GetBytes(float2);
            data.AddRange(GetByteList(byteLine));
            byteLine = BitConverter.GetBytes(float3);
            data.AddRange(GetByteList(byteLine));

            byte[] dataBytes = data.ToArray();

            data.Add(0x0A);
            Debug.WriteLine(data.Count());


            for (int i = dataBytes.Count()-1; i >=0; i--)
            {
                Debug.Write(dataBytes[i] + " ");
            }
            Debug.WriteLine("");

            string line = System.Text.Encoding.Default.GetString(dataBytes);



            //Here we have the Serial "received data"
            
            Debug.Write("The data is -->");
            Debug.Write(line);
            Debug.WriteLine("<--");




            //Remove the newline (is there when port.Readline())
            line = line.Trim();




            byte[] recevedBytes = Encoding.ASCII.GetBytes(line);

            Debug.Write("Sent Bytes (" + dataBytes.Count() + ")\t\t\t--> ");
            for (int i = dataBytes.Count() - 1; i >= 0; i--)
            {
                Debug.Write(dataBytes[i] + " ");
            }
            Debug.WriteLine("");

            //Issue is here

            //Printing the converted byte array, the uint32 values are the same, but not the float. they are somehow random. float2 seems to be correct
            Debug.Write("Received Bytes (" + recevedBytes.Count() + ")\t\t--> ");
            for (int i = recevedBytes.Count() - 1; i >= 0; i--)
            {
                Debug.Write(recevedBytes[i] + " ");
            }
            Debug.WriteLine("");



            //Checking the struct is empty and has same size as received data
            byte[] dataStructBytes = GetBytes(dataStruct);



            dataStruct = FromBytes(recevedBytes);


            //Printing the new struct
            foreach (var field in typeof(DataStructSend).GetFields(BindingFlags.Instance |
                                                 BindingFlags.NonPublic |
                                                 BindingFlags.Public))
            {
                Debug.WriteLine("{0} = {1}", field.Name, field.GetValue(dataStruct));
            }



        }
    }
}

使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用System.Linq;
运用系统反思;
使用System.Runtime.InteropServices;
使用系统文本;
使用System.Threading.Tasks;
名称空间会话测试
{
班级计划
{
公共静态列表GetByteList(字节[]数组)
{
List returnList=新列表();
对于(int i=0;i=0;i--)
{
Debug.Write(数据字节[i]+“”);
}
Debug.WriteLine(“”);
string line=System.Text.Encoding.Default.GetString(数据字节);
//这里是串行“接收数据”
Debug.Write(“数据为-->”;
Debug.Write(行);
Debug.WriteLine(“”);
对于(int i=dataBytes.Count()-1;i>=0;i--)
{
Debug.Write(数据字节[i]+“”);
}
Debug.WriteLine(“”);
//问题就在这里
//打印转换后的字节数组时,uint32值是相同的,但不是浮点数。它们是随机的。浮点数2似乎是正确的
Debug.Write(“接收字节(“+recevedBytes.Count()+”)\t\t-->”);
对于(int i=recevedBytes.Count()-1;i>=0;i--)
{
Debug.Write(recevedBytes[i]+“”);
}
Debug.WriteLine(“”);
//检查结构是否为空且与接收到的数据大小相同
字节[]数据结构字节=GetBytes(数据结构);
数据结构=FromBytes(recevedBytes);
//打印新结构
foreach(typeof中的var字段(DataStructSend).GetFields(BindingFlags.Instance|
BindingFlags.NonPublic|
(公众)
{
Debug.WriteLine(“{0}={1}”,field.Name,field.GetValue(dataStruct));
}
}
}
}

使用Encoding.Default对字符串进行编码,并使用Encoding.ASCII进行解码。
默认值不是ASCII。

System.Text.Encoding.Default
System.Text.Encoding.ASCII
是将
字节[]
编码和解码为
字符串的一种不同寻常的方法。你为什么不使用和?喂!我从一个8位微控制器接收一个作为字节数组的结构。我能换个基数吗?我认为发送数据的基数是8位,不是64位,对吗?嗨!谢谢你的快速回答。当我从ACII转换到ASCII时,我不会得到相同的结果。但我确实得到了正确的答案
Sent Bytes (24)         --> 70 199 104 0 70 83 80 0 70 129 24 0 0 0 0 3 0 0 0 2 0 0 0 1 
Received Bytes (24)     --> 70 63 104 0 70 83 80 0 70 63 24 0 0 0 0 3 0 0 0 2 0 0 0 1 
int1 = 1
int2 = 2
int3 = 3
float1 = 12230
float2 = 13524
float3 = 12250
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace ConverstionTest
{
    class Program
    {
        public static List<byte> GetByteList(byte[] array)
        {
            List<byte> returnList = new List<byte>();
            for (int i = 0; i < array.Count(); i++)
            {
                Debug.Write(array[i] + " ");
                returnList.Add(array[i]);
            }
            Debug.WriteLine("");
            return returnList;
        }

        public struct DataStructSend
        {
            public UInt32 int1;
            public UInt32 int2;
            public UInt32 int3;
            public float float1;
            public float float2;
            public float float3;
        }

        public static byte[] GetBytes(DataStructSend str)
        {
            int size = Marshal.SizeOf(str);
            byte[] arr = new byte[size];

            IntPtr ptr = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(str, ptr, true);
            Marshal.Copy(ptr, arr, 0, size);
            Marshal.FreeHGlobal(ptr);
            return arr;
        }

        public static DataStructSend FromBytes(byte[] arr)
        {
            DataStructSend str = new DataStructSend();

            int size = Marshal.SizeOf(str);
            IntPtr ptr = Marshal.AllocHGlobal(size);

            Marshal.Copy(arr, 0, ptr, size);

            str = (DataStructSend)Marshal.PtrToStructure(ptr, str.GetType());
            Marshal.FreeHGlobal(ptr);

            return str;
        }

        static void Main(string[] args)
        {
            Debug.WriteLine("Started...");


            //Just generating dummy serial data to "read"
            List<byte> data = new List<byte>();

            DataStructSend dataStruct = new DataStructSend();

            UInt32 int1 = 1;
            UInt32 int2 = 2;
            UInt32 int3 = 3;
            float float1 = 16524.0000003F;
            float float2 = 13524.0000002F;
            float float3 = 25524.0000001F;



            byte[] byteLine = BitConverter.GetBytes(int1);
            data.AddRange(GetByteList(byteLine));
            byteLine = BitConverter.GetBytes(int2);
            data.AddRange(GetByteList(byteLine));
            byteLine = BitConverter.GetBytes(int3);
            data.AddRange(GetByteList(byteLine));

            byteLine = BitConverter.GetBytes(float1);
            data.AddRange(GetByteList(byteLine));
            byteLine = BitConverter.GetBytes(float2);
            data.AddRange(GetByteList(byteLine));
            byteLine = BitConverter.GetBytes(float3);
            data.AddRange(GetByteList(byteLine));

            byte[] dataBytes = data.ToArray();

            data.Add(0x0A);
            Debug.WriteLine(data.Count());


            for (int i = dataBytes.Count()-1; i >=0; i--)
            {
                Debug.Write(dataBytes[i] + " ");
            }
            Debug.WriteLine("");

            string line = System.Text.Encoding.Default.GetString(dataBytes);



            //Here we have the Serial "received data"
            
            Debug.Write("The data is -->");
            Debug.Write(line);
            Debug.WriteLine("<--");




            //Remove the newline (is there when port.Readline())
            line = line.Trim();




            byte[] recevedBytes = Encoding.ASCII.GetBytes(line);

            Debug.Write("Sent Bytes (" + dataBytes.Count() + ")\t\t\t--> ");
            for (int i = dataBytes.Count() - 1; i >= 0; i--)
            {
                Debug.Write(dataBytes[i] + " ");
            }
            Debug.WriteLine("");

            //Issue is here

            //Printing the converted byte array, the uint32 values are the same, but not the float. they are somehow random. float2 seems to be correct
            Debug.Write("Received Bytes (" + recevedBytes.Count() + ")\t\t--> ");
            for (int i = recevedBytes.Count() - 1; i >= 0; i--)
            {
                Debug.Write(recevedBytes[i] + " ");
            }
            Debug.WriteLine("");



            //Checking the struct is empty and has same size as received data
            byte[] dataStructBytes = GetBytes(dataStruct);



            dataStruct = FromBytes(recevedBytes);


            //Printing the new struct
            foreach (var field in typeof(DataStructSend).GetFields(BindingFlags.Instance |
                                                 BindingFlags.NonPublic |
                                                 BindingFlags.Public))
            {
                Debug.WriteLine("{0} = {1}", field.Name, field.GetValue(dataStruct));
            }



        }
    }
}