将C代码移植到C#/解除引用指针

时间:2017-12-20 22:23:46

标签: c# c

如何将这段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声明为字节数组。

2 个答案:

答案 0 :(得分:6)

分解。我们在做什么? 从语义层面开始工作,而不是从指针层面开始

  • 我们有一个包含一定数量字节的字节数组。
  • 我们一次取两个字节,并将它们别名为16位无符号整数
  • 我们提取16位无符号整数,将其转换为32位无符号整数,并将其分配给数组元素。

现在我们有了规范。 为每个有趣的操作编写一个方法。唯一有趣的操作是将两个字节转换为一个ushort;其他一切都是由编译器完成的。

static ushort BytesToUshort(byte b1, byte b2)
{
   // You can implement this method
}

大。现在我们有了一个可以使用的工具。我们想要几个字节? i*2i*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。