0

我正在尝试使用StrucLayoutand从内存中获取字符串FieldOffset

但是我在理解如何byte工作时遇到了很多麻烦。

这是我的代码 ATM :

[StructLayout(LayoutKind.Explicit)]
public unsafe struct InfoDetails
{
    [FieldOffset(0x14)]
    public fixed sbyte Name[50];

    public string getName
    {
        get
        {
            fixed (sbyte* namePtr = Name)
            {
                return new string(namePtr);
            }
        }
    }
}

这段代码returnsT。预期结果是TEZ

关于我为什么做错的任何建议?谢谢

4

3 回答 3

1

您似乎对字符串编码有疑问。考虑以下测试代码:

unsafe
{
    InfoDetails d;
    var encoding = Encoding.Unicode;
    var stringBytes = encoding.GetBytes("TEZ");
    for(int i=0; i<stringBytes.Length; i++) d.Name[i] = (sbyte)stringBytes[i];
    Console.WriteLine(d.getName);
}

您确实会得到“T”,但是如果您将编码更改为Encoding.ASCII您将按预期得到“TEZ”。

解决方法:需要事先知道信息的编码,并据此生成字符串。看起来它是 Unicode,所以先试试这个:

fixed (sbyte* namePtr = Name)
{
  return new string(namePtr, 0, 50, Encoding.Unicode);
}
于 2018-05-18T07:36:06.563 回答
1

您可以将签名更改为:

[FieldOffset(0x14)]
public fixed char Name[25];

public string getName
{
    get
    {
        fixed (char* namePtr = Name)
        {
            return new string(namePtr);
        }
    }
}

请注意我如何更改sbyte并将char缓冲区的大小减半(因为sizeof(char)== 2)

或者您甚至可以更简单地将单个演员添加到char*

fixed (sbyte* namePtr = Name)
{
    return new string((char*)namePtr);
}

不改变任何其他东西。

于 2018-05-18T07:51:45.213 回答
0

感谢大家的回答,他们帮助我找到了一个可行的解决方案。我真的不知道它是否是最好的:

[StructLayout(LayoutKind.Explicit)]
    public unsafe struct InfoDetails
    {
        [FieldOffset(0x14)]
        public fixed byte Name[50];

        public string test
        {
            get
            {
                List<byte> clearBytes = new List<byte>();
                fixed (byte* namePtr = Name)
                {
                    for (int i = 0; i < 50; i++)
                    {
                        if (namePtr[i] == 0x0 && namePtr[i + 1] == 0x0)
                        {
                            break;
                        }
                        clearBytes.Add(namePtr[i]);
                    }
                    if (clearBytes.Count() % 2 != 0)
                    {
                        clearBytes.Add(0x00);
                    }
                    return Encoding.Unicode.GetString(clearBytes.ToArray());
                }
            }
        }

    }

非常感谢 !

于 2018-05-18T07:38:23.960 回答