PInvoke для функции GetLogicalProcessorInformation - PullRequest
8 голосов
/ 07 августа 2011

Я хочу вызвать через c # / PInvoke функцию GetLogicalProcessorInformation, но я застрял с SYSTEM_LOGICAL_PROCESSOR_INFORMATION struct и CACHE_DESCRIPTOR struct ,

Как мне определить эти структуры для правильного использования?

Основные проблемы:
1. SYSTEM_LOGICAL_PROCESSOR_INFORMATION имеет объединение в своем определении
2. SYSTEM_LOGICAL_PROCESSOR_INFORMATION имеет ULONGLONG в своем определении
3. CACHE_DESCRIPTOR имеет WORD и DWORD в своем определении.

Можете ли вы помочь мне с этими структурами?

Ответы [ 2 ]

12 голосов
/ 07 августа 2011

Обновлено : исправлена ​​сортировка структуры, которая должна выполняться вручную.

Это довольно грязный вызов P /. Даже если у вас есть определенные структуры и объединение, вызывать функцию нетривиально, потому что вам нужно упорядочить структуры вручную.

[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);
    }
}
4 голосов
/ 07 августа 2011

A DWORD представляет собой uint, а WORD представляет собой ushort.

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

enum PROCESSOR_CACHE_TYPE
{
    Unified = 0,
    Instruction = 1,
    Data = 2,
    Trace = 3,
}

A union - это структура с макетом Explicit и FieldOffset.

[StructLayout(LayoutKind.Sequential)]
struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION
{
    public UIntPtr ProcessorMask;
    public LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
    public ProcessorRelationUnion RelationUnion;
}

[StructLayout(LayoutKind.Explicit)]
struct ProcessorRelationUnion
{
    [FieldOffset(0)] public CACHE_DESCRIPTOR Cache;
    [FieldOffset(0)] public uint NumaNodeNumber;
    [FieldOffset(0)] public byte ProcessorCoreFlags;
    [FieldOffset(0)] private UInt64 Reserved1;
    [FieldOffset(8)] private UInt64 Reserved2;
}

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

enum LOGICAL_PROCESSOR_RELATIONSHIP : uint
{
    ProcessorCore = 0,
    NumaNode = 1,
    RelationCache = 2,
}

A ULONGLONG является UInt64. Это выравнивание структуры по 8-байтовой границе (24 байта). Как отметил Дэвид в комментариях, это необходимо, и по какой-то причине его не было в библиотеке Microsoft Interop.

Обновление: Добавлены недостающие структуры и ссылка на библиотеку взаимодействия Windows от Microsoft Research.

Источник: WindowsInteropLib / Kernel32.cs

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...