c# - GetLogicalProcessorInformation 函数的 PInvoke

标签 c# windows pinvoke cpu

我想通过 c#/PInvoke 调用 GetLogicalProcessorInformation功能,但我坚持 SYSTEM_LOGICAL_PROCESSOR_INFORMATION结构和 CACHE_DESCRIPTOR结构。

我应该如何定义这些结构以便正确使用?

主要问题:
1. SYSTEM_LOGICAL_PROCESSOR_INFORMATION 在其定义中有联合
2. SYSTEM_LOGICAL_PROCESSOR_INFORMATIONULONGLONG在它的定义中
3. CACHE_DESCRIPTOR 的定义中有WORDDWORD

你能帮我解决这些结构吗?

最佳答案

更新:修复了必须手动完成的结构编码。

这是一个非常困惑的 P/invoke。即使您定义了结构和联合,调用该函数也并非易事,因为您必须手动编码结构。

[StructLayout(LayoutKind.Sequential)]
public struct PROCESSORCORE
{
    public byte Flags;
};

[StructLayout(LayoutKind.Sequential)]
public struct NUMANODE
{
    public uint NodeNumber;
}

public enum PROCESSOR_CACHE_TYPE
{
    CacheUnified,
    CacheInstruction,
    CacheData,
    CacheTrace
}

[StructLayout(LayoutKind.Sequential)]
public struct CACHE_DESCRIPTOR
{
    public byte Level;
    public byte Associativity;
    public ushort LineSize;
    public uint Size;
    public PROCESSOR_CACHE_TYPE Type;
}

[StructLayout(LayoutKind.Explicit)]
public struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION_UNION
{
    [FieldOffset(0)]
    public PROCESSORCORE ProcessorCore;
    [FieldOffset(0)]
    public NUMANODE NumaNode;
    [FieldOffset(0)]
    public CACHE_DESCRIPTOR Cache;
    [FieldOffset(0)]
    private UInt64 Reserved1;
    [FieldOffset(8)]
    private UInt64 Reserved2;
}

public enum LOGICAL_PROCESSOR_RELATIONSHIP
{
    RelationProcessorCore,
    RelationNumaNode,
    RelationCache,
    RelationProcessorPackage,
    RelationGroup,
    RelationAll = 0xffff
}

public struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION
{
    public UIntPtr ProcessorMask;
    public LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
    public SYSTEM_LOGICAL_PROCESSOR_INFORMATION_UNION ProcessorInformation;
}

[DllImport(@"kernel32.dll", SetLastError=true)]
public static extern bool GetLogicalProcessorInformation(
    IntPtr Buffer,
    ref uint ReturnLength
);

private const int ERROR_INSUFFICIENT_BUFFER = 122;

public static SYSTEM_LOGICAL_PROCESSOR_INFORMATION[] MyGetLogicalProcessorInformation()
{
    uint ReturnLength = 0;
    GetLogicalProcessorInformation(IntPtr.Zero, ref ReturnLength);
    if (Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER)
    {
        IntPtr Ptr = Marshal.AllocHGlobal((int)ReturnLength);
        try
        {
            if (GetLogicalProcessorInformation(Ptr, ref ReturnLength))
            {
                int size = Marshal.SizeOf(typeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
                int len = (int)ReturnLength / size;
                SYSTEM_LOGICAL_PROCESSOR_INFORMATION[] Buffer = new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[len];
                IntPtr Item = Ptr;
                for (int i = 0; i < len; i++)
                {
                    Buffer[i] = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION)Marshal.PtrToStructure(Item, typeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
                    Item += size;
                }
                return Buffer;
            }
        }
        finally
        {
            Marshal.FreeHGlobal(Ptr);
        }
    }
    return null;
}

static void Main(string[] args)
{
    SYSTEM_LOGICAL_PROCESSOR_INFORMATION[] Buffer = MyGetLogicalProcessorInformation();
    for (int i=0; i<Buffer.Length; i++)
    {
        Console.WriteLine(Buffer[i].ProcessorMask);
    }
}

关于c# - GetLogicalProcessorInformation 函数的 PInvoke,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6972437/

相关文章:

c# - 从传递字节数组的 C# 调用 delphi dll 函数

c# - CPU利用率

c# - 将 json 字符串反序列化为 .NET 对象列表

c++ - 如何让 SWIG 在 Windows 上为 intptr_t 使用 64 位整数

windows - Web 平台安装程序.. 为什么?以及如何安装 SEO 工具包?

c# - 枚举网络 session

c# - P/Invoke 方法与结构使用联合

c# - 在 Visual Studio 2012 中运行到光标处

c# - 从 WinForms 中打开 WPF 窗口并将表单应用程序与 WPF 应用程序链接

windows - 批处理文件-删除某个字符之前的所有内容