无符号字符 * - 等效的 C#

unsigned char * - Equivalent C#

本文关键字:字符 无符号      更新时间:2023-10-16

我正在将库从C++移植到 C#,但遇到了一个我不确定如何解决的情况,其中包括将unsigned char *转换为unsigned int *

C++

unsigned int c4;
unsigned int c2;
unsigned int h4;
int pos(unsigned char *p)
{
    c4 = *(reinterpret_cast<unsigned int *>(p - 4));
    c2 = *(reinterpret_cast<unsigned short *>(p - 2));
    h4 = ((c4 >> 11) ^ c4) & (N4 - 1);
    if ((tab4[h4][0] != 0) && (tab4[h4][1] == c4))
    {
        c = 256;
        return (tab4[h4][0]);
    }
    c = 257;
    return (tab2[c2]);
}

C#(这是错误的(:

 public uint pos(byte p) 
 {
        c4 = (uint)(p - 4);
        c2 = (ushort)(p - 2);
        h4 = ((c4 >> 11) ^ c4) & (1 << 20 - 1);
        if ((tab4[h4, 0] != 0) && (tab4[h4, 1] == c4)) {
            c = 256;
            return (tab4[h4, 0]);
        }
        c = 257;
        return (tab2[c2]);
 }

我相信在 C# 示例中,您可以将byte p更改为 byte[],但是当涉及到将byte[]转换为单个 uint 值时,我一无所知。

此外,谁能向我解释一下,你为什么要对unsigned int *unsigned char *?它有什么目的?

任何帮助/推动方向都将非常有用。

有问题的行的翻译将是:

int pos(byte[] a, int offset)
{
    // Read the four bytes immediately preceding offset
    c4 = BitConverter.ToUInt32(a, offset - 4);
    // Read the two bytes immediately preceding offset
    c2 = BitConverter.ToUInt16(a, offset - 2);

并将调用从 x = pos(&buf[i])(即使在C++中也与 x = pos(buf + i) 相同(更改为

x = pos(buf, i);

需要注意的是,现有的C++代码是错误的,因为它违反了严格的别名规则。

在 C# 中实现类似功能不需要涉及逐条语句复制 C 版本的代码,尤其是在原始版本使用指针时。
当我们假设int为 32 位的体系结构时,可以像这样简化 C# 版本:

uint[] tab2;
uint[,] tab4;
ushort c;
public uint pos(uint c4)
{
    var h4 = ((c4 >> 11) ^ c4) & (1 << 20 - 1);
    if ((tab4[h4, 0] != 0) && (tab4[h4, 1] == c4))
    {
        c = 256;
        return (tab4[h4, 0]);
    }
    else
    {
        c = 257;
        var c2 = (c4 >> 16) & 0xffff; // HIWORD
        return (tab2[c2]);
    }
}
这种简化是可能的,因为 c4 和 c2

重叠:c2 是 c4 的高字,仅当 tab4 中的查找不匹配时才需要。

(标识符N4存在于原始代码中,但在您自己的翻译中替换为表达式 1<<20(。

调用代码必须遍历一个 int 数组,根据注释,这是可能的。虽然原始C++代码从偏移量 4 开始并回头看,但 C# 等效项将从偏移量 0 开始,这似乎是更自然的做法。

在C++代码中,您正在发送指向字符的指针,但通常 C# 不会使用这种方式处理内存,您需要数组而不是指针。

但是您可以使用unsafe关键字直接处理内存。https://msdn.microsoft.com/en-us/library/chfa2zb8.aspx