如何将这段C代码移植到C#?它是一个UPC密钥恢复工具。
hv
是一个包含4个元素的uint32_t
数组。 h1
是一个包含16个元素的uint8_t
数组
uint32_t hv[4] = ...
uint8_t h1[16] = ...
for (i = 0; i < 4; i++) {
hv[i] = *(uint16_t *)(h1 + i*2);
}
虽然这是有效的C代码,但我似乎无法将其移植到C#而不会给我带来错误。有人知道我能做什么吗?
我尝试将hv
声明为uint数组,将h1
声明为字节数组。
答案 0 :(得分:6)
分解。我们在做什么? 从语义层面开始工作,而不是从指针层面开始。
现在我们有了规范。 为每个有趣的操作编写一个方法。唯一有趣的操作是将两个字节转换为一个ushort;其他一切都是由编译器完成的。
static ushort BytesToUshort(byte b1, byte b2)
{
// You can implement this method
}
大。现在我们有了一个可以使用的工具。我们想要几个字节? i*2
和i*2+1
处的字节数。所以:
for (i = 0; i < 4; i++) {
hv[i] = BytesToUshort(h1[i*2], h1[i*2+1]);
}
我们已经完成了。
不要尝试将指针操作代码转换为C#;你可以做到,但它不会是好的C#代码。编写具有相同效果但使用C#惯例的代码。
一种可能有用的技术是重写代码,使其不那么糟糕的C代码;这很糟糕。如果您首先将原始代码重写为C:
uint16_t *ps = (uint16_t*)h1;
for (i = 0; i < 4; i++)
hv[i] = ps[i];
我敢说从概念上理解这里发生了什么会更容易。
答案 1 :(得分:1)
本质:
ushort[] hv = new ushort[4];
byte[] h1 = new byte[16];
for (int i = 0; i < 4; i++)
{
// note: this call is CPU-endian; if your data is not CPU-endian,
// you will need to write a known-endian op - aka "shift" and "or"
hv[i] = BitConverter.ToUInt16(h1, i * 2);
}
虽然我想知道是否更合适。
请注意,您还可以使用unsafe
C#代码使与C代码基本相同的代码(通过fixed
),并在即将到来的位中:这将非常适合Span<T>
,它允许在不同T
之间进行简单的thunk。