C# * 和 & 运算符用于指向数组
Posted
技术标签:
【中文标题】C# * 和 & 运算符用于指向数组【英文标题】:C# * and & operaor for pointing to array 【发布时间】:2019-06-23 19:42:35 【问题描述】:我正在将 C++ CRC 函数转换为 C#,但在函数参数中传递指向 (unsigned char) 字节数组的指针时遇到问题。在下面的 C++ 示例中
unsigned int CRC16_Calculation(unsigned char *buf, unsigned int len)
unsigned int ix;
unsigned int index;
unsigned int crc = 0;
for(ix=0; ix<len; ix++)
index = (high ^ buf[ix]) & 0x00FF;
crc = (low * 256) ^ Crc16Tbl[index];
return crc;
我能够将这个函数翻译成 C#。
public static unsafe ushort ComputeChecksum(byte[] buffer, ushort len)
ushort index;
ushort crc = 0;
for (int i = 0; i < len; ++i)
index = (ushort)((low ^ buffer[i]) & 0x00FF);
crc = (ushort)((high * 256) ^ table[index]);
return crc;
我需要使用C++中的函数如下:
crc= CRC16_Calculation(&Array[3], sizeof(Array)-3);
但是在 C# 中给我一个编译器错误。
ushort crc = ComputeChecksum(Array[3], (ushort)(Array.Length-3));
参数 1:无法从 'byte[]*' 转换为 'byte[]'。
'Program.ComputeChecksum(byte[], ushort)' 的最佳重载方法匹配有一些无效参数
问题是 C++ 函数使用对 unsigned char 数组的指针,而这在 C# 中是不可能的,仅在使用不安全时才对应?
【问题讨论】:
您说“我需要在 C++ 中按如下方式使用该函数......但在 C# 中它给了我”。问题是如何将 call 转换为函数?你能给我们看一个最小的调用示例吗? 它一定是不安全的吗?如果不是:不要“翻译”。写下它的作用,然后用“C#方式”实现它。像这样的翻译几乎不会导致合理的代码(根据我的经验)。 您可能会发现最简单的解决方案是在 C# 中添加一个额外的ushort offset
参数,并在距数组开头的那个偏移量处启动 CRC。
我添加了给出错误的 C# 函数调用。这仅在使用 Array[3] 时发生。添加数组将起作用。
【参考方案1】:
首先在 C# 中,只将数组传递给没有长度的方法就足够了,因为 Array
类包含 Length
属性。所以你可以重写你的方法来跟随(unsafe
不是必需的,因为你没有在 C# 代码中使用指针)
public static ushort ComputeChecksum(byte[] buffer)
ushort index;
ushort crc = 0;
for (int i = 0; i < buffer.Length; ++i) //using Length property
index = (ushort)((low ^ buffer[i]) & 0x00FF);
crc = (ushort)((high * 256) ^ table[index]);
return crc;
您的问题几乎没有解决方案。第一个是使用Linq
。你可以这样调用你的方法
ushort crc = ComputeChecksum(arr.Skip(3).ToArray());
要使用Skip
方法,您需要添加using System.Linq;
。
第二种解决方案是使用Span
。它需要 Visual Studio 2017(或带有更新编译器的 2015),至少 .NET framework 4.5 并使用 Nuget 包管理器添加 System.Memory
包。
var span = new Span<byte>(arr, 3, arr.Length - 3);
ushort crc = ComputeChecksum(span.ToArray());
最直接的解决方案是在您的方法中添加 offset
和 length
参数
public static ushort ComputeChecksum(byte[] buffer, int length, int offset)
ushort index;
ushort crc = 0;
for (int i = offset; i < length; ++i)
index = (ushort)((low ^ buffer[i]) & 0x00FF);
crc = (ushort)((high * 256) ^ table[index]);
return crc;
和用法
int offset = 3;
ushort crc = ComputeChecksum(arr, arr.Length - offset, offset);
【讨论】:
以上是关于C# * 和 & 运算符用于指向数组的主要内容,如果未能解决你的问题,请参考以下文章