为GetLogicalProcessorInformation函数调用PInvoke

我想调用通过C#/ PInvoke GetLogicalProcessorInformation函数,但我坚持与SYSTEM_LOGICAL_PROCESSOR_INFORMATION结构和CACHE_DESCRIPTOR结构。

我应该如何定义这些结构的正确用法?

主要问题:
1. SYSTEM_LOGICAL_PROCESSOR_INFORMATION在它的定义中有union
2. SYSTEM_LOGICAL_PROCESSOR_INFORMATION在其定义中有ULONGLONG
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); } } 

DWORD是一个uintWORD是一个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, } 

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, } 

ULONGLONG是一个UInt64 这是结构对齐8字节的边界(24字节)。 正如David在评论中指出的那样,这是Microsoft Interop库所缺少的。

更新:添加缺少的结构和链接到Microsoft研究的Windows互操作库。

来源: WindowsInteropLib / coreel32.cs