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));
}
}
}
}