【问题标题】:Read an exact one struct field读取一个精确的结构字段
【发布时间】:2021-02-06 16:26:12
【问题描述】:

获取系统信息的代码如下:

using System;
using System.Runtime.InteropServices;

public class win{
    [StructLayout(LayoutKind.Sequential)]
    public struct SYSTEM_INFO{
        public ushort wProcessorArchitecture;
        public ushort wReserved;
        public uint dwPageSize;
        public IntPtr lpMinimumApplicationAddress;
        public IntPtr lpMaximumApplicationAddress;
        public UIntPtr dwActiveProcessorMask;
        public uint dwNumberOfProcessors;
        public uint dwProcessorType;
        public uint dwAllocationGranularity;
        public ushort wProcessorLevel;
        public ushort wProcessorRevision;
    };
    [DllImport("kernel32.dll")]
    public static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSystemInfo);

    public static void Main(){
        var sysInfo = new SYSTEM_INFO();

        GetNativeSystemInfo(ref sysInfo);
        var res = sysInfo.wProcessorArchitecture;
        Console.WriteLine(res);
    }
}

输出为9。 有没有一种方法可以在不定义所有结构的情况下准确读取一个结构字段?

例如,获取第一个字段的值:

using System;
using System.Runtime.InteropServices;

public class win{
    [DllImport("kernel32.dll")]
    public static extern void GetNativeSystemInfo(IntPtr lpSystemInfo);

    public static void Main(){
        var sysInfo = Marshal.AllocHGlobal(96);
        GetNativeSystemInfo(sysInfo);
        var res = Marshal.ReadByte(sysInfo, 0);
        Console.WriteLine(res);
    }
}

输出为9。但是如何获得例如第三个字段的值?缓冲区内可能有一些标记,可以告诉我,新字段开始了吗?

【问题讨论】:

  • 数据是一团二进制数据。如果您有两个字节 (1, 2) 和一个 int (0x100),那么它看起来像二进制的 01 02 00 00 01 00。数据中没有其他数据可以告诉您哪种数据类型位于哪个偏移量。这就是结构定义的工作。您需要通过定义结构或手动硬编码所有非常容易出错的偏移量来知道位于哪个偏移量。你为什么要这样做?
  • 您正在使用 C API 进行通信。在 C 中,数据的结构在类型系统中进行编码。类型系统仅对编译器可用。一旦完成,目标代码中就没有任何元数据了。如果您需要理解这些数据,您将不得不以您使用的任何语言复制其结构。如果您不想自己编写结构定义,请查看C#/Win32

标签: c# .net winapi


【解决方案1】:

如何获取第三个字段的值?

只需在前两个字段之后设置偏移量:

using System;
using System.Runtime.InteropServices;

public class win {
    [DllImport("kernel32.dll")]
    public static extern void GetNativeSystemInfo(IntPtr lpSystemInfo);

    public static void Main() {
        var offset = 4;
        var sysInfo = Marshal.AllocHGlobal(offset + 4);
        GetNativeSystemInfo(sysInfo);
        var res = Marshal.ReadInt32(sysInfo, offset);
        Marshal.FreeHGlobal(sysInfo);
        Console.WriteLine(res);
    }
}

输出:4096 ( dwPageSize )

【讨论】:

    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 2022-11-02
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2014-07-06
    • 2017-10-07
    • 2021-03-27
    相关资源
    最近更新 更多