如何将我的代码从 C# 转换为 C++ 以获得 CRC 函数?
How do I translate my code from C# to C++ for a CRC function?
我在 C# 中有以下代码来计算 CRC,它的工作方式与我希望的一样。
public byte crc_8(byte[] byteArray)
{
ushort reg_crc = 0;
for(int i = 0; i<byteArray.Length; i++)
{
reg_crc ^= byteArray[i];
for(int j = 0; j < 8; j++)
{
if((reg_crc & 0x01) == 1)
{
reg_crc = (ushort)((reg_crc >> 1) ^ 0xE5);
}
else
{
reg_crc = (ushort)(reg_crc >> 1);
}
}
}
reg_crc = (byte)(reg_crc & 0xFF);
return (byte)reg_crc;
}
我还需要将同样的功能添加到 C++ 代码项目中,但我是 C++ 的新手。据我所知,我不确定如何处理 for 循环内的代码。另请注意,RX_PACKET_SIZE
等同于 byteArray.Length
,因为它可以用于相同的目的。我知道没关系。
static uint8_t crc_8(unit8_t array_to_process [])
{
uint16_t reg_crc = 0;
for(int i = 0; i < RX_PACKET_SIZE; i++)
{
}
}
数组在 C++ 中的工作方式略有不同。它们不是对象;它们基本上只是一种在内存中重复 n
次的数据类型。在您的情况下,它会重复 uint_8
次 RX_PACKET_SIZE
次。您不传递数组本身;相反,您将指针传递给数组的第一个元素。这是您的代码的 C++ 版本:
uint8_t crc_8(uint8_t* byteArray, size_t length)
{
uint8_t reg_crc = 0;
for(int i = 0; i < length; i++)
{
reg_crc ^= byteArray[i];
for(int j = 0; j < 8; j++)
{
if((reg_crc & 0x01) == 1)
{
reg_crc = (reg_crc >> 1) ^ 0xE5;
}
else
{
reg_crc = reg_crc >> 1;
}
}
}
return reg_crc;
}
我将 reg_crc
的类型更改为 uint8_t
,因为您对其执行的 none 操作使用了后半部分的位。鉴于你知道长度是RX_PACKET_SIZE
,我们也可以给length
一个默认值:
uint8_t crc_8(uint8_t* byteArray, size_t length = RX_PACKET_SIZE)
{
uint8_t reg_crc = 0;
for(int i = 0; i < length; i++)
{
reg_crc ^= byteArray[i];
for(int j = 0; j < 8; j++)
{
if((reg_crc & 0x01) == 1)
{
reg_crc = (reg_crc >> 1) ^ 0xE5;
}
else
{
reg_crc = reg_crc >> 1;
}
}
}
return reg_crc;
}
对未来的帮助说明:
C++ 标准库提供了一个名为 std::vector
的 class。 std::vector
具有与 C# 中的 ArrayList 相同的功能,但由于 C++ 模板的工作方式,它可能会更快。
您可以为 crc_8
编写一个重载,这样您就可以向它传递一个向量:
// The & after std::vector<uint8_t> means that it'll pass
// by reference, instead of passing by value. Passing by
// reference is usually the preferable option because nothing
// gets copied, making it much faster.
uint8_t crc_8(std::vector<uint8_t>& bytes) {
//This calls the the version shown above
return crc_8(bytes.data(), bytes.size());
}
如果编译器说 uint8_t
没有定义,那是因为你需要把 #include <cstdint>
放在文件的顶部。
我在 C# 中有以下代码来计算 CRC,它的工作方式与我希望的一样。
public byte crc_8(byte[] byteArray)
{
ushort reg_crc = 0;
for(int i = 0; i<byteArray.Length; i++)
{
reg_crc ^= byteArray[i];
for(int j = 0; j < 8; j++)
{
if((reg_crc & 0x01) == 1)
{
reg_crc = (ushort)((reg_crc >> 1) ^ 0xE5);
}
else
{
reg_crc = (ushort)(reg_crc >> 1);
}
}
}
reg_crc = (byte)(reg_crc & 0xFF);
return (byte)reg_crc;
}
我还需要将同样的功能添加到 C++ 代码项目中,但我是 C++ 的新手。据我所知,我不确定如何处理 for 循环内的代码。另请注意,RX_PACKET_SIZE
等同于 byteArray.Length
,因为它可以用于相同的目的。我知道没关系。
static uint8_t crc_8(unit8_t array_to_process [])
{
uint16_t reg_crc = 0;
for(int i = 0; i < RX_PACKET_SIZE; i++)
{
}
}
数组在 C++ 中的工作方式略有不同。它们不是对象;它们基本上只是一种在内存中重复 n
次的数据类型。在您的情况下,它会重复 uint_8
次 RX_PACKET_SIZE
次。您不传递数组本身;相反,您将指针传递给数组的第一个元素。这是您的代码的 C++ 版本:
uint8_t crc_8(uint8_t* byteArray, size_t length)
{
uint8_t reg_crc = 0;
for(int i = 0; i < length; i++)
{
reg_crc ^= byteArray[i];
for(int j = 0; j < 8; j++)
{
if((reg_crc & 0x01) == 1)
{
reg_crc = (reg_crc >> 1) ^ 0xE5;
}
else
{
reg_crc = reg_crc >> 1;
}
}
}
return reg_crc;
}
我将 reg_crc
的类型更改为 uint8_t
,因为您对其执行的 none 操作使用了后半部分的位。鉴于你知道长度是RX_PACKET_SIZE
,我们也可以给length
一个默认值:
uint8_t crc_8(uint8_t* byteArray, size_t length = RX_PACKET_SIZE)
{
uint8_t reg_crc = 0;
for(int i = 0; i < length; i++)
{
reg_crc ^= byteArray[i];
for(int j = 0; j < 8; j++)
{
if((reg_crc & 0x01) == 1)
{
reg_crc = (reg_crc >> 1) ^ 0xE5;
}
else
{
reg_crc = reg_crc >> 1;
}
}
}
return reg_crc;
}
对未来的帮助说明:
C++ 标准库提供了一个名为 std::vector
的 class。 std::vector
具有与 C# 中的 ArrayList 相同的功能,但由于 C++ 模板的工作方式,它可能会更快。
您可以为 crc_8
编写一个重载,这样您就可以向它传递一个向量:
// The & after std::vector<uint8_t> means that it'll pass
// by reference, instead of passing by value. Passing by
// reference is usually the preferable option because nothing
// gets copied, making it much faster.
uint8_t crc_8(std::vector<uint8_t>& bytes) {
//This calls the the version shown above
return crc_8(bytes.data(), bytes.size());
}
如果编译器说 uint8_t
没有定义,那是因为你需要把 #include <cstdint>
放在文件的顶部。