在 C# 中从通过串口接收的字节组装一个结构体
在 CI 中,只需将数据缓冲区数组中的 memcpy 复制到结构体的地址即可。 我不知道如何在 C# 中为桌面端执行此操作。这是我在 C# 中的结构
struct frame_type
{
public UInt32 start_of_frame;
public UInt32 frame_id;
public UInt16 frame_len;
public UInt32 crc;
public UInt32 end_of_frame;
}
,我有一个 Datareceived 串行端口回调,下面的 dataIn 变量是一个字符串,但显然我可以对其进行其他更改,以便更轻松地获取所有这些字节并组装框架。
private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
dataIN = port.ReadExisting();
//increment variable and when i have 34 bytes assemble a frame
//and checkl if it is an ack frame.
bytes_received_count++;
if(bytes_received_count == 34)
{
//assemble a frame_type frame
}
this.Invoke(new EventHandler(sendFirmware));
}
所以欢迎任何建议。
更新: 经过一番研究后,我最终得到了这段代码:
private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
for (int i = 0; i < 34; i++)
{
bytes_received[i] = (byte)port.ReadByte();
}
assemble_frame_from_port_bytes();
// this.Invoke(new EventHandler(sendFirmware));
}
public void assemble_frame_from_port_bytes()
{
frame.start_of_frame = (UInt32)(bytes_received[3] << 24 | bytes_received[2] << 16 | bytes_received[1] << 8 | bytes_received[0] << 0);
frame.frame_id = (UInt32)(bytes_received[7] << 24 | bytes_received[6] << 16 | bytes_received[5] << 8 | bytes_received[4] << 0);
frame.frame_len = (UInt16)(bytes_received[9] << 8 | bytes_received[8] << 0);
int idx = 10;
for (int i = 0; i < 16; i++)
{
payload[i] = bytes_received[idx++];
}
frame.crc = (UInt32)(bytes_received[29] << 24 | bytes_received[28] << 16 | bytes_received[27] << 8 | bytes_received[26] << 0);
frame.end_of_frame = (UInt32)(bytes_received[33] << 24 | bytes_received[32] << 16 | bytes_received[31] << 8 | bytes_received[30] << 0);
}
它完成了工作,是不是很棒?我不知道,但现阶段它达到了目的。 C# 无疑是一个非常强大的工具,但在傻瓜手中它就会被削弱,哈哈。
In C I simply do a memcpy from my data buffer array to the address of my struct.
I am not sure how to do this in C# for the desktop side of things. This is my struct in C#
struct frame_type
{
public UInt32 start_of_frame;
public UInt32 frame_id;
public UInt16 frame_len;
public UInt32 crc;
public UInt32 end_of_frame;
}
And I have a Datareceived serial port callback, the dataIn variable below is a string but obviously I can change it something else to make it easier to grab all those bytes and assemble the frame.
private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
dataIN = port.ReadExisting();
//increment variable and when i have 34 bytes assemble a frame
//and checkl if it is an ack frame.
bytes_received_count++;
if(bytes_received_count == 34)
{
//assemble a frame_type frame
}
this.Invoke(new EventHandler(sendFirmware));
}
So any suggestions are welcome.
UPDATE:
I ended up with this code after some research:
private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
for (int i = 0; i < 34; i++)
{
bytes_received[i] = (byte)port.ReadByte();
}
assemble_frame_from_port_bytes();
// this.Invoke(new EventHandler(sendFirmware));
}
public void assemble_frame_from_port_bytes()
{
frame.start_of_frame = (UInt32)(bytes_received[3] << 24 | bytes_received[2] << 16 | bytes_received[1] << 8 | bytes_received[0] << 0);
frame.frame_id = (UInt32)(bytes_received[7] << 24 | bytes_received[6] << 16 | bytes_received[5] << 8 | bytes_received[4] << 0);
frame.frame_len = (UInt16)(bytes_received[9] << 8 | bytes_received[8] << 0);
int idx = 10;
for (int i = 0; i < 16; i++)
{
payload[i] = bytes_received[idx++];
}
frame.crc = (UInt32)(bytes_received[29] << 24 | bytes_received[28] << 16 | bytes_received[27] << 8 | bytes_received[26] << 0);
frame.end_of_frame = (UInt32)(bytes_received[33] << 24 | bytes_received[32] << 16 | bytes_received[31] << 8 | bytes_received[30] << 0);
}
It gets the job done, is it great? I dont know but it serves its purpose at this stage. C# surely is a great powerful tool but in the hands of a fool it is crippled haha.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我想下面是类似的东西,但我无法测试它:
它应该允许您直接将长度为 18 的字节数组分配给结构
当然,它是万恶之源和安全的方法可能看起来像:
ps;通过以下方式获取字节可能是最简单的:
I suppose the following is something similar, but I'm not in a position to test it:
It should allow you to just straight assign a byte array of length 18 to the struct
Of course, it is the root of all evil and a safe approach would perhaps look like:
ps; it's perhaps easiest to get your bytes by something like:
好吧,大警告,我没有串行端口,所以无法测试
核心是使用 BinaryReader 从字节流中读取序列化元素,ReadUInt32 拉出接下来的 4 个字节并编组到 UIn32 等。
棘手的一点是将字节从 thr 端口获取到流,因为我们无法将流直接连接到端口(我不知道如何做到这一点),所以我使用 MemoryStream,顾名思义,它是内存中的字节流
ok big caveat, I have no serial port so cannot test
the core is using BinaryReader this reads serialized elements from a byte stream, ReadUInt32 pulls the next 4 bytes and marshalls to a UIn32 etc.
The fiddly bit is getting the bytes from thr port into a stream since we cant connect a stream directly to the port (I coulsnt see how to do it) so I use a MemoryStream which, as the name suggests , is a byte stream in memory