c # - PInvoke til GetLogicalProcessorInformation Funktionen

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg vil ringe via c #/PInvoke funktionen GetLogicalProcessorInformation, men jeg er fast med SYSTEM\_LOGICAL\_PROCESSOR\_INFORMATION struct og CACHE\_DESCRIPTOR struct. [22] [23] [24]]]


Hvordan skal jeg definere disse strukturer for korrekt brug?


Vigtigste problemer:

  1. SYSTEM\_LOGICAL\_PROCESSOR\_INFORMATION har union i sin definition

  2. SYSTEM\_LOGICAL\_PROCESSOR\_INFORMATION har ULONGLONG i sin definition

  3. CACHE\_DESCRIPTOR har WORD og DWORD i sin definition. [25]


Kan du hjælpe mig med disse strukturer?

Bedste reference


Opdateret : Fastgør strukturen, der skal opstilles, som skal udføres manuelt.


Dette er ret rodet P/påberåbe sig. Selv når du har strukturer og fagforeningen defineret, er det ikke ubetydeligt at kalde funktionen, fordi du skal marchere strukturerne manuelt.


[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);
    }
}

Andre referencer 1


A DWORD er en uint og WORD er en 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 er en struktur med et Explicit layout og 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,
}


En ULONGLONG er en UInt64. Det er at justere strukturen til 8 byte grænse (24 bytes). Som David påpegede i kommentarerne, er det påkrævet og af en eller anden grund manglede det fra Microsoft Interop biblioteket.


Opdatering: Tilføjet manglende strukturer og link til Windows Interop Library fra Microsoft Research.


Kilde: WindowsInteropLib/Kernel32.cs [26]