2011-08-07 19 views
6

के लिए PInvoke मैं GetLogicalProcessorInformation फ़ंक्शन को C#/PInvoke के माध्यम से कॉल करना चाहता हूं, लेकिन मैं SYSTEM_LOGICAL_PROCESSOR_INFORMATION संरचना और CACHE_DESCRIPTOR संरचना से फंस गया हूं।GetLogicalProcessorInformation Function

मुझे इन structs को सही उपयोग के लिए कैसे परिभाषित करना चाहिए?

मुख्य समस्याओं:
1. SYSTEM_LOGICAL_PROCESSOR_INFORMATION इसकी परिभाषा
3. CACHE_DESCRIPTORWORD और इसकी परिभाषा में DWORD है में अपनी परिभाषा संघ है
2. SYSTEM_LOGICAL_PROCESSOR_INFORMATION है ULONGLONG

क्या आप इन संरचनाओं के साथ मेरी मदद कर सकते हैं?

+0

डाउनवोट के लिए कोई कारण? – VMAtm

उत्तर

10

अपडेट किया गया: संरचना मार्शलिंग जो मैन्युअल रूप से किया जा सकता है तय की।

यह काफी गन्दा पी/आक्रमण है। यहां तक ​​कि जब आपके पास structs और यूनियन परिभाषित होते हैं, तो फ़ंक्शन को कॉल करने के लिए यह गैर-तुच्छ है क्योंकि आपको संरचनाओं को मैन्युअल रूप से मार्शल करना होगा।

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

+1। – Dennis

+0

मुझे निम्न संकलन त्रुटि मिली है (.NET 1.1 पर) 'ऑपरेटर' + = '' System.IntPtr 'और' int 'प्रकार के संचालन पर लागू नहीं किया जा सकता है। क्या मैं IntPtr के बजाय 'int *' का उपयोग कर सकता हूं? – VMAtm

+0

मैंने निम्नलिखित का उपयोग करने की कोशिश की: 'आइटम = नया IntPtr (Item.ToInt32() + आकार); और यह काम किया। मैं बताउंगा, अगर मैं 'int *' का उपयोग कर सकता हूं। – VMAtm

4

DWORDuint और WORDushort है।

[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 बाइट्स) में संरेखित करना है। जैसा कि डेविड ने टिप्पणियों में बताया, यह आवश्यक है और किसी कारण से यह माइक्रोसॉफ्ट इंटरऑप लाइब्रेरी से गायब था।

अद्यतन: माइक्रोसॉफ्ट रिसर्च से विंडोज इंटरऑप लाइब्रेरी में लापता संरचनाएं और लिंक जोड़ा गया।

स्रोत: WindowsInteropLib/Kernel32.cs

+1

हालांकि यह उत्तर सभी अपवर्तकों को आकर्षित कर रहा है, लेकिन ऐसा लगता है कि मुझे दो महत्वपूर्ण तरीकों से गंभीर रूप से कमी हो रही है। 'उलझन [2] आरक्षित' सदस्य को अनदेखा करना मतलब है कि संरचना गलत आकार के बाइट्स की बजाय 20 बाइट्स होने के कारण गलत आकार है। और सबसे महत्वपूर्ण बात यह है कि वास्तव में फ़ंक्शन को कॉल करने का कोई उल्लेख नहीं है जो सही होने के लिए मुश्किल है। –

+2

डेविड के बाहर इंगित करने के लिए धन्यवाद - मैं बस आपका जवाब पढ़ रहा था और एक ही चीज़ को महसूस किया। अधिक संपूर्ण उत्तर के लिए – Dennis

संबंधित मुद्दे